<!DOCTYPE html>
<!-- saved from url=(0127)https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>WebPerf WG F2F June 2019 Minutes</title><link rel="shortcut icon" href="https://ssl.gstatic.com/docs/documents/images/kix-favicon7.ico"><meta name="referrer" content="strict-origin-when-cross-origin"><style type="text/css" nonce="">
      @import url("https://fonts.googleapis.com/css?family=Google+Sans");
      @import url("https://fonts.googleapis.com/css?family=Roboto");

      body {
        font-family: Roboto, arial, sans, sans-serif;
        margin: 0;
      }

      iframe {
        border: 0;
        frameborder: 0;
        height: 100%;
        width: 100%;
      }

      #header {
        align-items: center;
        background: white;
        border-bottom: 1px #ccc solid;
        display: flex;
        height: 60px;
        justify-content: space-between;
        position: fixed;
        top: 0;
        width: 100%;
        z-index: 100;
      }

      #header #title {
        font-family: 'Google Sans';
        font-size: large;
        margin: auto 0 auto 20px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 70%;
      }

      #header #interval {
        margin: auto 25px auto 0;
        font-family: Roboto;
        font-size: small;;
      }

      #footer {
        background: #f0f0f0;
        border-bottom: 1px #ccc solid;
        bottom: 0;
        font-family: Roboto;
        font-size: small;
        padding: 10px 10px;
        position: fixed;
        text-align: center;
        width: 100%;
      }

      #contents {
        padding: 100px 20% 50px 20%;
      }

      @media only screen and (max-device-width: 800px) {
        #header {
          border-bottom-width: 5px;
          height: auto;
          display: block;
        }

        #header #title {
          font-size: 3em;
          margin: auto 0 auto 20px;
          width: 90%;
        }

        #header #interval {
          font-size: 1.5em;
          margin: 10px 0 auto 25px;
        }

        #contents {
          padding: 150px 5% 80px;
        }

        #footer {
          font-size: 2em;
        }
      }

      .dash {
        padding: 0 6px;
      }
    </style></head><body><div id="header"><div id="title">WebPerf WG F2F June 2019 Minutes</div><div id="interval"><span></span></div></div><div id="contents"><style type="text/css">@import url('https://themes.googleusercontent.com/fonts/css?kit=OPeqXG-QxW3ZD8BtmPikfA');ol.lst-kix_k8lu2ylie4bt-4.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-4 0}.lst-kix_uehujnp5bzt9-8>li:before{content:"\0025a0  "}ul.lst-kix_5jnfbo9vknc3-7{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-8{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-5{list-style-type:none}ul.lst-kix_z9041a6ln04m-0{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-6{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-3{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-4{list-style-type:none}.lst-kix_uehujnp5bzt9-4>li:before{content:"\0025cb  "}.lst-kix_uehujnp5bzt9-6>li:before{content:"\0025cf  "}ul.lst-kix_z9041a6ln04m-3{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-1{list-style-type:none}ul.lst-kix_z9041a6ln04m-4{list-style-type:none}.lst-kix_445fzt9hauve-8>li:before{content:"-  "}ul.lst-kix_5jnfbo9vknc3-2{list-style-type:none}ul.lst-kix_z9041a6ln04m-1{list-style-type:none}ul.lst-kix_z9041a6ln04m-2{list-style-type:none}ul.lst-kix_5jnfbo9vknc3-0{list-style-type:none}.lst-kix_uehujnp5bzt9-3>li:before{content:"\0025cf  "}.lst-kix_uehujnp5bzt9-7>li:before{content:"\0025cb  "}ul.lst-kix_z9041a6ln04m-7{list-style-type:none}ul.lst-kix_z9041a6ln04m-8{list-style-type:none}ul.lst-kix_z9041a6ln04m-5{list-style-type:none}ul.lst-kix_z9041a6ln04m-6{list-style-type:none}.lst-kix_uehujnp5bzt9-5>li:before{content:"\0025a0  "}ul.lst-kix_u0fqahpsffbf-1{list-style-type:none}ul.lst-kix_u0fqahpsffbf-2{list-style-type:none}.lst-kix_445fzt9hauve-2>li:before{content:"-  "}.lst-kix_445fzt9hauve-3>li:before{content:"-  "}ul.lst-kix_u0fqahpsffbf-3{list-style-type:none}ul.lst-kix_u0fqahpsffbf-4{list-style-type:none}.lst-kix_xml3pa5n5vjf-0>li:before{content:"\0025cf  "}.lst-kix_445fzt9hauve-0>li:before{content:"-  "}.lst-kix_445fzt9hauve-1>li:before{content:"-  "}.lst-kix_445fzt9hauve-4>li:before{content:"-  "}.lst-kix_445fzt9hauve-5>li:before{content:"-  "}ul.lst-kix_u0fqahpsffbf-0{list-style-type:none}.lst-kix_xml3pa5n5vjf-2>li:before{content:"\0025a0  "}.lst-kix_445fzt9hauve-6>li:before{content:"-  "}.lst-kix_445fzt9hauve-7>li:before{content:"-  "}.lst-kix_uehujnp5bzt9-0>li:before{content:"\0025cf  "}.lst-kix_uehujnp5bzt9-2>li:before{content:"\0025a0  "}ul.lst-kix_u0fqahpsffbf-5{list-style-type:none}ul.lst-kix_u0fqahpsffbf-6{list-style-type:none}.lst-kix_i6pzozb09tpp-0>li{counter-increment:lst-ctn-kix_i6pzozb09tpp-0}ul.lst-kix_u0fqahpsffbf-7{list-style-type:none}.lst-kix_xml3pa5n5vjf-1>li:before{content:"\0025cb  "}ul.lst-kix_u0fqahpsffbf-8{list-style-type:none}.lst-kix_uehujnp5bzt9-1>li:before{content:"\0025cb  "}ul.lst-kix_16pzzom86drc-5{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-0{list-style-type:none}.lst-kix_c0d94mf0u9td-3>li:before{content:"\0025cf  "}.lst-kix_jf43zqpqkez-7>li:before{content:"\0025cb  "}ul.lst-kix_16pzzom86drc-6{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-1{list-style-type:none}ul.lst-kix_16pzzom86drc-3{list-style-type:none}.lst-kix_c0d94mf0u9td-2>li:before{content:"\0025a0  "}.lst-kix_c0d94mf0u9td-4>li:before{content:"\0025cb  "}ul.lst-kix_16pzzom86drc-4{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-4{list-style-type:none}.lst-kix_jf43zqpqkez-5>li:before{content:"\0025a0  "}ul.lst-kix_v6i4vcxz3xlh-5{list-style-type:none}ul.lst-kix_16pzzom86drc-7{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-2{list-style-type:none}.lst-kix_jf43zqpqkez-6>li:before{content:"\0025cf  "}ul.lst-kix_16pzzom86drc-8{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-3{list-style-type:none}.lst-kix_c0d94mf0u9td-7>li:before{content:"\0025cb  "}.lst-kix_jf43zqpqkez-3>li:before{content:"\0025cf  "}.lst-kix_c0d94mf0u9td-0>li:before{content:"\0025cf  "}.lst-kix_c0d94mf0u9td-8>li:before{content:"\0025a0  "}.lst-kix_c0d94mf0u9td-1>li:before{content:"\0025cb  "}.lst-kix_jf43zqpqkez-4>li:before{content:"\0025cb  "}.lst-kix_xml3pa5n5vjf-6>li:before{content:"\0025cf  "}.lst-kix_6168y9xo6jas-3>li:before{content:"\0025cf  "}.lst-kix_6168y9xo6jas-4>li:before{content:"\0025cb  "}.lst-kix_jf43zqpqkez-1>li:before{content:"\0025cb  "}.lst-kix_xml3pa5n5vjf-4>li:before{content:"\0025cb  "}.lst-kix_xml3pa5n5vjf-8>li:before{content:"\0025a0  "}.lst-kix_6168y9xo6jas-2>li:before{content:"\0025a0  "}.lst-kix_jf43zqpqkez-2>li:before{content:"\0025a0  "}.lst-kix_xml3pa5n5vjf-3>li:before{content:"\0025cf  "}.lst-kix_xml3pa5n5vjf-7>li:before{content:"\0025cb  "}.lst-kix_6168y9xo6jas-0>li:before{content:"\0025cf  "}.lst-kix_c0d94mf0u9td-6>li:before{content:"\0025cf  "}ul.lst-kix_16pzzom86drc-1{list-style-type:none}.lst-kix_c0d94mf0u9td-5>li:before{content:"\0025a0  "}ul.lst-kix_16pzzom86drc-2{list-style-type:none}.lst-kix_6168y9xo6jas-1>li:before{content:"\0025cb  "}.lst-kix_jf43zqpqkez-0>li:before{content:"\0025cf  "}.lst-kix_xml3pa5n5vjf-5>li:before{content:"\0025a0  "}ul.lst-kix_16pzzom86drc-0{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-0{list-style-type:none}ul.lst-kix_84l1nt15bcm1-0{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-1{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-2{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-3{list-style-type:none}.lst-kix_h3e2fv4cmf9v-8>li:before{content:"\0025a0  "}.lst-kix_5jnfbo9vknc3-6>li:before{content:"\0025cf  "}ol.lst-kix_k8lu2ylie4bt-8{list-style-type:none}.lst-kix_5jnfbo9vknc3-7>li:before{content:"\0025cb  "}ol.lst-kix_k8lu2ylie4bt-4{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-5{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-6{list-style-type:none}.lst-kix_5jnfbo9vknc3-8>li:before{content:"\0025a0  "}ol.lst-kix_k8lu2ylie4bt-7{list-style-type:none}ul.lst-kix_84l1nt15bcm1-7{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-8{list-style-type:none}ul.lst-kix_84l1nt15bcm1-8{list-style-type:none}ul.lst-kix_84l1nt15bcm1-5{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-6{list-style-type:none}ul.lst-kix_84l1nt15bcm1-6{list-style-type:none}ul.lst-kix_v6i4vcxz3xlh-7{list-style-type:none}ul.lst-kix_84l1nt15bcm1-3{list-style-type:none}ul.lst-kix_84l1nt15bcm1-4{list-style-type:none}ul.lst-kix_84l1nt15bcm1-1{list-style-type:none}ul.lst-kix_84l1nt15bcm1-2{list-style-type:none}.lst-kix_k8lu2ylie4bt-2>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-2}.lst-kix_spmomcke4os8-7>li:before{content:"\0025cb  "}ul.lst-kix_445fzt9hauve-8{list-style-type:none}ul.lst-kix_445fzt9hauve-4{list-style-type:none}ul.lst-kix_445fzt9hauve-5{list-style-type:none}ul.lst-kix_445fzt9hauve-6{list-style-type:none}ul.lst-kix_445fzt9hauve-7{list-style-type:none}.lst-kix_z9041a6ln04m-7>li:before{content:"\0025cb  "}.lst-kix_spmomcke4os8-0>li:before{content:"\0025cf  "}.lst-kix_h3e2fv4cmf9v-3>li:before{content:"\0025cf  "}.lst-kix_df6fn36a3u4o-6>li:before{content:"\0025cf  "}.lst-kix_h3e2fv4cmf9v-5>li:before{content:"\0025a0  "}.lst-kix_h3e2fv4cmf9v-7>li:before{content:"\0025cb  "}.lst-kix_5jnfbo9vknc3-5>li:before{content:"\0025a0  "}.lst-kix_z9041a6ln04m-5>li:before{content:"\0025a0  "}.lst-kix_df6fn36a3u4o-8>li:before{content:"\0025a0  "}.lst-kix_df6fn36a3u4o-0>li:before{content:"\0025cf  "}.lst-kix_5jnfbo9vknc3-1>li:before{content:"\0025cb  "}.lst-kix_5jnfbo9vknc3-3>li:before{content:"\0025cf  "}.lst-kix_df6fn36a3u4o-2>li:before{content:"\0025a0  "}.lst-kix_z9041a6ln04m-3>li:before{content:"\0025cf  "}.lst-kix_z9041a6ln04m-1>li:before{content:"\0025cb  "}.lst-kix_6168y9xo6jas-5>li:before{content:"\0025a0  "}.lst-kix_df6fn36a3u4o-4>li:before{content:"\0025cb  "}ul.lst-kix_445fzt9hauve-0{list-style-type:none}ul.lst-kix_445fzt9hauve-1{list-style-type:none}.lst-kix_h3e2fv4cmf9v-1>li:before{content:"\0025cb  "}ul.lst-kix_445fzt9hauve-2{list-style-type:none}ul.lst-kix_445fzt9hauve-3{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-2.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-2 0}.lst-kix_6168y9xo6jas-7>li:before{content:"\0025cb  "}.lst-kix_x68yhsmhn47y-2>li:before{content:"\0025a0  "}.lst-kix_jf43zqpqkez-8>li:before{content:"\0025a0  "}ul.lst-kix_92zwylia2gw-8{list-style-type:none}.lst-kix_x68yhsmhn47y-4>li:before{content:"\0025cb  "}.lst-kix_jxj988oac1jn-0>li:before{content:"\0025cf  "}.lst-kix_tt0bruxtd04w-8>li:before{content:"\0025a0  "}.lst-kix_x68yhsmhn47y-6>li:before{content:"\0025cf  "}ul.lst-kix_tt0bruxtd04w-8{list-style-type:none}.lst-kix_zhlpi08mbuyv-5>li:before{content:"-  "}.lst-kix_tt0bruxtd04w-2>li:before{content:"\0025a0  "}ul.lst-kix_tt0bruxtd04w-7{list-style-type:none}ul.lst-kix_tt0bruxtd04w-6{list-style-type:none}ul.lst-kix_tt0bruxtd04w-5{list-style-type:none}ul.lst-kix_tt0bruxtd04w-4{list-style-type:none}ul.lst-kix_tt0bruxtd04w-3{list-style-type:none}.lst-kix_x68yhsmhn47y-8>li:before{content:"\0025a0  "}ul.lst-kix_tt0bruxtd04w-2{list-style-type:none}ul.lst-kix_tt0bruxtd04w-1{list-style-type:none}ul.lst-kix_92zwylia2gw-6{list-style-type:none}ul.lst-kix_92zwylia2gw-7{list-style-type:none}.lst-kix_tt0bruxtd04w-6>li:before{content:"\0025cf  "}ul.lst-kix_92zwylia2gw-4{list-style-type:none}ul.lst-kix_92zwylia2gw-5{list-style-type:none}ul.lst-kix_92zwylia2gw-2{list-style-type:none}.lst-kix_b71z0bwzk1nz-8>li:before{content:"\0025a0  "}ul.lst-kix_92zwylia2gw-3{list-style-type:none}.lst-kix_zhlpi08mbuyv-7>li:before{content:"-  "}.lst-kix_tt0bruxtd04w-4>li:before{content:"\0025cb  "}ul.lst-kix_92zwylia2gw-0{list-style-type:none}ul.lst-kix_92zwylia2gw-1{list-style-type:none}.lst-kix_b71z0bwzk1nz-6>li:before{content:"\0025cf  "}.lst-kix_84l1nt15bcm1-0>li:before{content:"\0025cf  "}ul.lst-kix_tt0bruxtd04w-0{list-style-type:none}.lst-kix_jxj988oac1jn-8>li:before{content:"\0025a0  "}.lst-kix_b71z0bwzk1nz-4>li:before{content:"\0025cb  "}.lst-kix_zhlpi08mbuyv-3>li:before{content:"-  "}.lst-kix_tt0bruxtd04w-0>li:before{content:"\0025cf  "}.lst-kix_84l1nt15bcm1-2>li:before{content:"\0025a0  "}.lst-kix_84l1nt15bcm1-4>li:before{content:"\0025cb  "}.lst-kix_jxj988oac1jn-2>li:before{content:"\0025a0  "}.lst-kix_jxj988oac1jn-4>li:before{content:"\0025cb  "}ul.lst-kix_xml3pa5n5vjf-8{list-style-type:none}ul.lst-kix_xml3pa5n5vjf-6{list-style-type:none}ul.lst-kix_xml3pa5n5vjf-7{list-style-type:none}ul.lst-kix_xml3pa5n5vjf-4{list-style-type:none}.lst-kix_b71z0bwzk1nz-2>li:before{content:"\0025a0  "}ul.lst-kix_xml3pa5n5vjf-5{list-style-type:none}.lst-kix_zhlpi08mbuyv-1>li:before{content:"-  "}.lst-kix_jxj988oac1jn-6>li:before{content:"\0025cf  "}ul.lst-kix_xml3pa5n5vjf-2{list-style-type:none}ul.lst-kix_xml3pa5n5vjf-3{list-style-type:none}.lst-kix_84l1nt15bcm1-6>li:before{content:"\0025cf  "}ul.lst-kix_xml3pa5n5vjf-0{list-style-type:none}.lst-kix_b71z0bwzk1nz-0>li:before{content:"\0025cf  "}ul.lst-kix_xml3pa5n5vjf-1{list-style-type:none}.lst-kix_k8lu2ylie4bt-7>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-7,lower-latin) ". "}.lst-kix_84l1nt15bcm1-8>li:before{content:"\0025a0  "}.lst-kix_k8lu2ylie4bt-3>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-3,decimal) ". "}ul.lst-kix_h3e2fv4cmf9v-3{list-style-type:none}ul.lst-kix_h3e2fv4cmf9v-2{list-style-type:none}ul.lst-kix_h3e2fv4cmf9v-1{list-style-type:none}ul.lst-kix_h3e2fv4cmf9v-0{list-style-type:none}.lst-kix_k8lu2ylie4bt-2>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-2,lower-roman) ". "}ul.lst-kix_h3e2fv4cmf9v-7{list-style-type:none}.lst-kix_ys3qtqydi841-4>li:before{content:"\0025cb  "}.lst-kix_aglivdlbfii-0>li:before{content:"\0025cf  "}ul.lst-kix_h3e2fv4cmf9v-6{list-style-type:none}.lst-kix_qza8dbp12114-7>li:before{content:"\0025cb  "}ul.lst-kix_h3e2fv4cmf9v-5{list-style-type:none}.lst-kix_ys3qtqydi841-5>li:before{content:"\0025a0  "}ul.lst-kix_h3e2fv4cmf9v-4{list-style-type:none}.lst-kix_qza8dbp12114-4>li:before{content:"\0025cb  "}.lst-kix_qza8dbp12114-8>li:before{content:"\0025a0  "}.lst-kix_aglivdlbfii-1>li:before{content:"\0025cb  "}ul.lst-kix_h3e2fv4cmf9v-8{list-style-type:none}.lst-kix_ys3qtqydi841-8>li:before{content:"\0025a0  "}.lst-kix_k8lu2ylie4bt-6>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-6,decimal) ". "}.lst-kix_zhlpi08mbuyv-0>li{counter-increment:lst-ctn-kix_zhlpi08mbuyv-0}ul.lst-kix_c0d94mf0u9td-0{list-style-type:none}.lst-kix_aglivdlbfii-8>li:before{content:"\0025a0  "}ul.lst-kix_c0d94mf0u9td-1{list-style-type:none}ul.lst-kix_c0d94mf0u9td-2{list-style-type:none}ul.lst-kix_c0d94mf0u9td-3{list-style-type:none}ul.lst-kix_c0d94mf0u9td-4{list-style-type:none}ul.lst-kix_c0d94mf0u9td-5{list-style-type:none}.lst-kix_qza8dbp12114-0>li:before{content:"\0025cf  "}ul.lst-kix_c0d94mf0u9td-6{list-style-type:none}.lst-kix_aglivdlbfii-5>li:before{content:"\0025a0  "}ul.lst-kix_c0d94mf0u9td-7{list-style-type:none}.lst-kix_aglivdlbfii-4>li:before{content:"\0025cb  "}.lst-kix_qza8dbp12114-3>li:before{content:"\0025cf  "}.lst-kix_ys3qtqydi841-0>li:before{content:"\0025cf  "}.lst-kix_ys3qtqydi841-1>li:before{content:"\0025cb  "}.lst-kix_sbdbv2a1ucvm-1>li:before{content:"\0025cb  "}.lst-kix_sbdbv2a1ucvm-2>li:before{content:"\0025a0  "}.lst-kix_8e9je34qm6o7-7>li:before{content:"\0025cb  "}.lst-kix_x68yhsmhn47y-0>li:before{content:"\0025cf  "}.lst-kix_8e9je34qm6o7-4>li:before{content:"\0025cb  "}.lst-kix_8e9je34qm6o7-8>li:before{content:"\0025a0  "}.lst-kix_sbdbv2a1ucvm-5>li:before{content:"\0025a0  "}.lst-kix_sbdbv2a1ucvm-6>li:before{content:"\0025cf  "}.lst-kix_8e9je34qm6o7-3>li:before{content:"\0025cf  "}.lst-kix_9lbma9vfugut-8>li:before{content:"\0025a0  "}ul.lst-kix_c0d94mf0u9td-8{list-style-type:none}.lst-kix_9lbma9vfugut-0>li:before{content:"\0025cf  "}.lst-kix_9lbma9vfugut-7>li:before{content:"\0025cb  "}.lst-kix_spmomcke4os8-2>li:before{content:"\0025a0  "}.lst-kix_spmomcke4os8-3>li:before{content:"\0025cf  "}.lst-kix_8e9je34qm6o7-0>li:before{content:"\0025cf  "}.lst-kix_9lbma9vfugut-3>li:before{content:"\0025cf  "}.lst-kix_k8lu2ylie4bt-5>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-5}.lst-kix_9lbma9vfugut-4>li:before{content:"\0025cb  "}ul.lst-kix_8e9je34qm6o7-2{list-style-type:none}ul.lst-kix_uehujnp5bzt9-4{list-style-type:none}ul.lst-kix_8e9je34qm6o7-1{list-style-type:none}ul.lst-kix_uehujnp5bzt9-5{list-style-type:none}ul.lst-kix_8e9je34qm6o7-0{list-style-type:none}ul.lst-kix_uehujnp5bzt9-2{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-8{list-style-type:none}ul.lst-kix_uehujnp5bzt9-3{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-7{list-style-type:none}ul.lst-kix_8e9je34qm6o7-6{list-style-type:none}ul.lst-kix_uehujnp5bzt9-0{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-6{list-style-type:none}.lst-kix_spmomcke4os8-6>li:before{content:"\0025cf  "}ul.lst-kix_8e9je34qm6o7-5{list-style-type:none}ul.lst-kix_uehujnp5bzt9-1{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-5{list-style-type:none}ul.lst-kix_8e9je34qm6o7-4{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-4{list-style-type:none}ul.lst-kix_8e9je34qm6o7-3{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-3{list-style-type:none}ul.lst-kix_6k6ln47x41zf-7{list-style-type:none}ul.lst-kix_6k6ln47x41zf-6{list-style-type:none}.lst-kix_bmdfdiffj318-6>li:before{content:"-  "}ul.lst-kix_6k6ln47x41zf-8{list-style-type:none}ul.lst-kix_uehujnp5bzt9-8{list-style-type:none}ul.lst-kix_uehujnp5bzt9-6{list-style-type:none}ul.lst-kix_uehujnp5bzt9-7{list-style-type:none}ul.lst-kix_aglivdlbfii-8{list-style-type:none}.lst-kix_z9041a6ln04m-6>li:before{content:"\0025cf  "}.lst-kix_bmdfdiffj318-2>li:before{content:"-  "}ul.lst-kix_aglivdlbfii-6{list-style-type:none}ul.lst-kix_aglivdlbfii-7{list-style-type:none}.lst-kix_df6fn36a3u4o-7>li:before{content:"\0025cb  "}ul.lst-kix_aglivdlbfii-4{list-style-type:none}ul.lst-kix_aglivdlbfii-5{list-style-type:none}ul.lst-kix_aglivdlbfii-2{list-style-type:none}.lst-kix_h3e2fv4cmf9v-4>li:before{content:"\0025cb  "}ul.lst-kix_aglivdlbfii-3{list-style-type:none}ul.lst-kix_aglivdlbfii-0{list-style-type:none}ul.lst-kix_aglivdlbfii-1{list-style-type:none}.lst-kix_zigfdtz9pu7t-6>li:before{content:"\0025cf  "}.lst-kix_5jnfbo9vknc3-2>li:before{content:"\0025a0  "}.lst-kix_z9041a6ln04m-2>li:before{content:"\0025a0  "}.lst-kix_df6fn36a3u4o-3>li:before{content:"\0025cf  "}.lst-kix_zigfdtz9pu7t-2>li:before{content:"\0025a0  "}ul.lst-kix_6k6ln47x41zf-1{list-style-type:none}ul.lst-kix_6k6ln47x41zf-0{list-style-type:none}.lst-kix_h3e2fv4cmf9v-0>li:before{content:"\0025cf  "}ul.lst-kix_6k6ln47x41zf-3{list-style-type:none}.lst-kix_6168y9xo6jas-6>li:before{content:"\0025cf  "}ul.lst-kix_6k6ln47x41zf-2{list-style-type:none}ul.lst-kix_6k6ln47x41zf-5{list-style-type:none}ul.lst-kix_6k6ln47x41zf-4{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-2{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-1{list-style-type:none}ul.lst-kix_8e9je34qm6o7-8{list-style-type:none}ul.lst-kix_sbdbv2a1ucvm-0{list-style-type:none}ul.lst-kix_8e9je34qm6o7-7{list-style-type:none}.lst-kix_i6pzozb09tpp-5>li:before{content:"-  "}.lst-kix_92zwylia2gw-3>li:before{content:"\0025cf  "}ul.lst-kix_a8qujuk25xw2-0{list-style-type:none}ul.lst-kix_a8qujuk25xw2-1{list-style-type:none}.lst-kix_x68yhsmhn47y-3>li:before{content:"\0025cf  "}ul.lst-kix_a8qujuk25xw2-4{list-style-type:none}.lst-kix_a8qujuk25xw2-3>li:before{content:"\0025cf  "}ul.lst-kix_a8qujuk25xw2-5{list-style-type:none}ul.lst-kix_a8qujuk25xw2-2{list-style-type:none}.lst-kix_k8lu2ylie4bt-0>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-0}ul.lst-kix_a8qujuk25xw2-3{list-style-type:none}.lst-kix_92zwylia2gw-7>li:before{content:"\0025cb  "}.lst-kix_jxj988oac1jn-1>li:before{content:"\0025cb  "}.lst-kix_i6pzozb09tpp-1>li:before{content:"-  "}.lst-kix_tt0bruxtd04w-1>li:before{content:"\0025cb  "}.lst-kix_o3c3kswyzx42-4>li:before{content:"\0025cb  "}.lst-kix_x68yhsmhn47y-7>li:before{content:"\0025cb  "}ul.lst-kix_a8qujuk25xw2-8{list-style-type:none}.lst-kix_tt0bruxtd04w-5>li:before{content:"\0025a0  "}.lst-kix_o3c3kswyzx42-0>li:before{content:"\0025cf  "}ul.lst-kix_a8qujuk25xw2-6{list-style-type:none}ul.lst-kix_a8qujuk25xw2-7{list-style-type:none}.lst-kix_k8lu2ylie4bt-7>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-7}.lst-kix_zhlpi08mbuyv-8>li:before{content:"-  "}.lst-kix_v6i4vcxz3xlh-1>li:before{content:"\0025cb  "}.lst-kix_v6i4vcxz3xlh-5>li:before{content:"\0025a0  "}.lst-kix_84l1nt15bcm1-1>li:before{content:"\0025cb  "}.lst-kix_b71z0bwzk1nz-5>li:before{content:"\0025a0  "}.lst-kix_zhlpi08mbuyv-4>li:before{content:"-  "}.lst-kix_84l1nt15bcm1-5>li:before{content:"\0025a0  "}.lst-kix_o3c3kswyzx42-8>li:before{content:"\0025a0  "}.lst-kix_jxj988oac1jn-5>li:before{content:"\0025a0  "}.lst-kix_b71z0bwzk1nz-1>li:before{content:"\0025cb  "}.lst-kix_zhlpi08mbuyv-0>li:before{content:"" counter(lst-ctn-kix_zhlpi08mbuyv-0,decimal) ". "}ul.lst-kix_b71z0bwzk1nz-0{list-style-type:none}ul.lst-kix_b71z0bwzk1nz-1{list-style-type:none}ul.lst-kix_b71z0bwzk1nz-2{list-style-type:none}.lst-kix_e9lsjgl3agqq-5>li:before{content:"\0025a0  "}.lst-kix_e9lsjgl3agqq-7>li:before{content:"\0025cb  "}ul.lst-kix_b71z0bwzk1nz-3{list-style-type:none}.lst-kix_e9lsjgl3agqq-2>li:before{content:"\0025a0  "}.lst-kix_e9lsjgl3agqq-6>li:before{content:"\0025cf  "}ul.lst-kix_b71z0bwzk1nz-8{list-style-type:none}.lst-kix_e9lsjgl3agqq-3>li:before{content:"\0025cf  "}ul.lst-kix_b71z0bwzk1nz-4{list-style-type:none}ul.lst-kix_b71z0bwzk1nz-5{list-style-type:none}ul.lst-kix_b71z0bwzk1nz-6{list-style-type:none}.lst-kix_e9lsjgl3agqq-4>li:before{content:"\0025cb  "}ul.lst-kix_b71z0bwzk1nz-7{list-style-type:none}.lst-kix_k8lu2ylie4bt-4>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-4}ul.lst-kix_zigfdtz9pu7t-2{list-style-type:none}ul.lst-kix_zigfdtz9pu7t-3{list-style-type:none}ul.lst-kix_zigfdtz9pu7t-4{list-style-type:none}.lst-kix_e9lsjgl3agqq-1>li:before{content:"\0025cb  "}.lst-kix_u0fqahpsffbf-1>li:before{content:"\0025cb  "}ul.lst-kix_zigfdtz9pu7t-5{list-style-type:none}ul.lst-kix_zigfdtz9pu7t-6{list-style-type:none}ul.lst-kix_zigfdtz9pu7t-7{list-style-type:none}ul.lst-kix_zigfdtz9pu7t-8{list-style-type:none}.lst-kix_e9lsjgl3agqq-0>li:before{content:"\0025cf  "}.lst-kix_u0fqahpsffbf-0>li:before{content:"\0025cf  "}.lst-kix_6k6ln47x41zf-2>li:before{content:"\0025a0  "}.lst-kix_6k6ln47x41zf-3>li:before{content:"\0025cf  "}.lst-kix_u0fqahpsffbf-3>li:before{content:"\0025cf  "}.lst-kix_u0fqahpsffbf-5>li:before{content:"\0025a0  "}.lst-kix_6k6ln47x41zf-1>li:before{content:"\0025cb  "}.lst-kix_6k6ln47x41zf-5>li:before{content:"\0025a0  "}ul.lst-kix_zigfdtz9pu7t-0{list-style-type:none}.lst-kix_u0fqahpsffbf-2>li:before{content:"\0025a0  "}.lst-kix_u0fqahpsffbf-6>li:before{content:"\0025cf  "}ul.lst-kix_zigfdtz9pu7t-1{list-style-type:none}.lst-kix_6k6ln47x41zf-6>li:before{content:"\0025cf  "}.lst-kix_6k6ln47x41zf-7>li:before{content:"\0025cb  "}.lst-kix_6k6ln47x41zf-0>li:before{content:"\0025cf  "}.lst-kix_6k6ln47x41zf-8>li:before{content:"\0025a0  "}.lst-kix_u0fqahpsffbf-4>li:before{content:"\0025cb  "}.lst-kix_u0fqahpsffbf-7>li:before{content:"\0025cb  "}.lst-kix_6k6ln47x41zf-4>li:before{content:"\0025cb  "}.lst-kix_u0fqahpsffbf-8>li:before{content:"\0025a0  "}.lst-kix_i6pzozb09tpp-7>li:before{content:"-  "}.lst-kix_a8qujuk25xw2-5>li:before{content:"\0025a0  "}.lst-kix_y4sl13ifkgmm-4>li:before{content:"\0025cb  "}.lst-kix_y4sl13ifkgmm-6>li:before{content:"\0025cf  "}.lst-kix_a8qujuk25xw2-6>li:before{content:"\0025cf  "}.lst-kix_a8qujuk25xw2-7>li:before{content:"\0025cb  "}.lst-kix_i6pzozb09tpp-8>li:before{content:"-  "}.lst-kix_y4sl13ifkgmm-5>li:before{content:"\0025a0  "}.lst-kix_a8qujuk25xw2-8>li:before{content:"\0025a0  "}.lst-kix_y4sl13ifkgmm-0>li:before{content:"\0025cf  "}.lst-kix_y4sl13ifkgmm-8>li:before{content:"\0025a0  "}ul.lst-kix_i6pzozb09tpp-8{list-style-type:none}ul.lst-kix_i6pzozb09tpp-7{list-style-type:none}.lst-kix_y4sl13ifkgmm-7>li:before{content:"\0025cb  "}ul.lst-kix_i6pzozb09tpp-6{list-style-type:none}ul.lst-kix_bmdfdiffj318-0{list-style-type:none}ul.lst-kix_i6pzozb09tpp-5{list-style-type:none}ul.lst-kix_i6pzozb09tpp-4{list-style-type:none}ul.lst-kix_bmdfdiffj318-2{list-style-type:none}ul.lst-kix_i6pzozb09tpp-3{list-style-type:none}ul.lst-kix_bmdfdiffj318-1{list-style-type:none}ul.lst-kix_i6pzozb09tpp-2{list-style-type:none}ul.lst-kix_bmdfdiffj318-4{list-style-type:none}ul.lst-kix_i6pzozb09tpp-1{list-style-type:none}ul.lst-kix_bmdfdiffj318-3{list-style-type:none}ul.lst-kix_bmdfdiffj318-6{list-style-type:none}ul.lst-kix_bmdfdiffj318-5{list-style-type:none}ul.lst-kix_bmdfdiffj318-8{list-style-type:none}ul.lst-kix_bmdfdiffj318-7{list-style-type:none}.lst-kix_16pzzom86drc-1>li:before{content:"\0025cb  "}.lst-kix_16pzzom86drc-0>li:before{content:"\0025cf  "}.lst-kix_16pzzom86drc-2>li:before{content:"\0025a0  "}ol.lst-kix_k8lu2ylie4bt-3.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-3 0}.lst-kix_16pzzom86drc-3>li:before{content:"\0025cf  "}.lst-kix_16pzzom86drc-4>li:before{content:"\0025cb  "}.lst-kix_16pzzom86drc-6>li:before{content:"\0025cf  "}.lst-kix_16pzzom86drc-5>li:before{content:"\0025a0  "}.lst-kix_16pzzom86drc-7>li:before{content:"\0025cb  "}.lst-kix_k8lu2ylie4bt-8>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-8}.lst-kix_y4sl13ifkgmm-1>li:before{content:"\0025cb  "}ol.lst-kix_zhlpi08mbuyv-0.start{counter-reset:lst-ctn-kix_zhlpi08mbuyv-0 0}.lst-kix_y4sl13ifkgmm-2>li:before{content:"\0025a0  "}.lst-kix_16pzzom86drc-8>li:before{content:"\0025a0  "}.lst-kix_e9lsjgl3agqq-8>li:before{content:"\0025a0  "}.lst-kix_y4sl13ifkgmm-3>li:before{content:"\0025cf  "}ul.lst-kix_spmomcke4os8-8{list-style-type:none}ul.lst-kix_spmomcke4os8-6{list-style-type:none}ul.lst-kix_spmomcke4os8-7{list-style-type:none}ul.lst-kix_spmomcke4os8-4{list-style-type:none}.lst-kix_bmdfdiffj318-7>li:before{content:"-  "}ul.lst-kix_spmomcke4os8-5{list-style-type:none}ul.lst-kix_spmomcke4os8-2{list-style-type:none}ul.lst-kix_spmomcke4os8-3{list-style-type:none}ul.lst-kix_spmomcke4os8-0{list-style-type:none}.lst-kix_bmdfdiffj318-1>li:before{content:"-  "}ul.lst-kix_spmomcke4os8-1{list-style-type:none}.lst-kix_zigfdtz9pu7t-5>li:before{content:"\0025a0  "}ol.lst-kix_i6pzozb09tpp-0.start{counter-reset:lst-ctn-kix_i6pzozb09tpp-0 0}.lst-kix_bmdfdiffj318-5>li:before{content:"-  "}.lst-kix_bmdfdiffj318-3>li:before{content:"-  "}.lst-kix_zigfdtz9pu7t-7>li:before{content:"\0025cb  "}ul.lst-kix_ys3qtqydi841-8{list-style-type:none}ul.lst-kix_ys3qtqydi841-7{list-style-type:none}.lst-kix_zigfdtz9pu7t-1>li:before{content:"\0025cb  "}ul.lst-kix_ys3qtqydi841-6{list-style-type:none}ul.lst-kix_ys3qtqydi841-5{list-style-type:none}.lst-kix_zigfdtz9pu7t-3>li:before{content:"\0025cf  "}ul.lst-kix_ys3qtqydi841-0{list-style-type:none}ul.lst-kix_jxj988oac1jn-7{list-style-type:none}ul.lst-kix_jxj988oac1jn-6{list-style-type:none}ul.lst-kix_jxj988oac1jn-5{list-style-type:none}.lst-kix_sbdbv2a1ucvm-8>li:before{content:"\0025a0  "}ul.lst-kix_jxj988oac1jn-4{list-style-type:none}ul.lst-kix_ys3qtqydi841-4{list-style-type:none}ul.lst-kix_jxj988oac1jn-3{list-style-type:none}ul.lst-kix_ys3qtqydi841-3{list-style-type:none}ul.lst-kix_jxj988oac1jn-2{list-style-type:none}ul.lst-kix_ys3qtqydi841-2{list-style-type:none}ul.lst-kix_jxj988oac1jn-1{list-style-type:none}ul.lst-kix_ys3qtqydi841-1{list-style-type:none}ul.lst-kix_jxj988oac1jn-0{list-style-type:none}.lst-kix_i6pzozb09tpp-6>li:before{content:"-  "}ul.lst-kix_jxj988oac1jn-8{list-style-type:none}.lst-kix_a8qujuk25xw2-4>li:before{content:"\0025cb  "}.lst-kix_a8qujuk25xw2-2>li:before{content:"\0025a0  "}.lst-kix_92zwylia2gw-2>li:before{content:"\0025a0  "}.lst-kix_92zwylia2gw-6>li:before{content:"\0025cf  "}.lst-kix_i6pzozb09tpp-4>li:before{content:"-  "}.lst-kix_a8qujuk25xw2-0>li:before{content:"\0025cf  "}.lst-kix_92zwylia2gw-0>li:before{content:"\0025cf  "}.lst-kix_92zwylia2gw-8>li:before{content:"\0025a0  "}.lst-kix_i6pzozb09tpp-2>li:before{content:"-  "}.lst-kix_o3c3kswyzx42-3>li:before{content:"\0025cf  "}.lst-kix_i6pzozb09tpp-0>li:before{content:"" counter(lst-ctn-kix_i6pzozb09tpp-0,decimal) ". "}.lst-kix_o3c3kswyzx42-1>li:before{content:"\0025cb  "}.lst-kix_92zwylia2gw-4>li:before{content:"\0025cb  "}.lst-kix_v6i4vcxz3xlh-2>li:before{content:"\0025a0  "}.lst-kix_v6i4vcxz3xlh-6>li:before{content:"\0025cf  "}.lst-kix_v6i4vcxz3xlh-0>li:before{content:"\0025cf  "}.lst-kix_v6i4vcxz3xlh-8>li:before{content:"\0025a0  "}.lst-kix_o3c3kswyzx42-5>li:before{content:"\0025a0  "}ul.lst-kix_9lbma9vfugut-4{list-style-type:none}ul.lst-kix_9lbma9vfugut-5{list-style-type:none}ul.lst-kix_9lbma9vfugut-2{list-style-type:none}ul.lst-kix_9lbma9vfugut-3{list-style-type:none}ul.lst-kix_9lbma9vfugut-8{list-style-type:none}ul.lst-kix_9lbma9vfugut-6{list-style-type:none}ul.lst-kix_9lbma9vfugut-7{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-0.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-0 0}.lst-kix_o3c3kswyzx42-7>li:before{content:"\0025cb  "}ol.lst-kix_zhlpi08mbuyv-0{list-style-type:none}.lst-kix_v6i4vcxz3xlh-4>li:before{content:"\0025cb  "}ul.lst-kix_9lbma9vfugut-0{list-style-type:none}ul.lst-kix_9lbma9vfugut-1{list-style-type:none}ul.lst-kix_jf43zqpqkez-7{list-style-type:none}ul.lst-kix_jf43zqpqkez-6{list-style-type:none}ul.lst-kix_jf43zqpqkez-5{list-style-type:none}ul.lst-kix_jf43zqpqkez-4{list-style-type:none}.lst-kix_k8lu2ylie4bt-3>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-3}.lst-kix_k8lu2ylie4bt-4>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-4,lower-latin) ". "}.lst-kix_k8lu2ylie4bt-8>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-8,lower-roman) ". "}ul.lst-kix_jf43zqpqkez-8{list-style-type:none}ul.lst-kix_jf43zqpqkez-3{list-style-type:none}ul.lst-kix_jf43zqpqkez-2{list-style-type:none}ul.lst-kix_jf43zqpqkez-1{list-style-type:none}ul.lst-kix_jf43zqpqkez-0{list-style-type:none}ul.lst-kix_zhlpi08mbuyv-1{list-style-type:none}ul.lst-kix_zhlpi08mbuyv-2{list-style-type:none}.lst-kix_qza8dbp12114-6>li:before{content:"\0025cf  "}.lst-kix_ys3qtqydi841-6>li:before{content:"\0025cf  "}.lst-kix_aglivdlbfii-2>li:before{content:"\0025a0  "}.lst-kix_qza8dbp12114-5>li:before{content:"\0025a0  "}ul.lst-kix_o3c3kswyzx42-7{list-style-type:none}ul.lst-kix_o3c3kswyzx42-8{list-style-type:none}.lst-kix_ys3qtqydi841-7>li:before{content:"\0025cb  "}.lst-kix_k8lu2ylie4bt-5>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-5,lower-roman) ". "}ol.lst-kix_k8lu2ylie4bt-1.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-1 0}.lst-kix_aglivdlbfii-6>li:before{content:"\0025cf  "}.lst-kix_qza8dbp12114-1>li:before{content:"\0025cb  "}.lst-kix_qza8dbp12114-2>li:before{content:"\0025a0  "}ul.lst-kix_zhlpi08mbuyv-7{list-style-type:none}ul.lst-kix_zhlpi08mbuyv-8{list-style-type:none}ul.lst-kix_zhlpi08mbuyv-5{list-style-type:none}ul.lst-kix_zhlpi08mbuyv-6{list-style-type:none}.lst-kix_aglivdlbfii-3>li:before{content:"\0025cf  "}ul.lst-kix_zhlpi08mbuyv-3{list-style-type:none}ul.lst-kix_zhlpi08mbuyv-4{list-style-type:none}.lst-kix_ys3qtqydi841-3>li:before{content:"\0025cf  "}.lst-kix_k8lu2ylie4bt-1>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-1,lower-latin) ". "}.lst-kix_ys3qtqydi841-2>li:before{content:"\0025a0  "}.lst-kix_k8lu2ylie4bt-0>li:before{content:"" counter(lst-ctn-kix_k8lu2ylie4bt-0,decimal) ". "}.lst-kix_aglivdlbfii-7>li:before{content:"\0025cb  "}.lst-kix_x68yhsmhn47y-1>li:before{content:"\0025cb  "}.lst-kix_sbdbv2a1ucvm-0>li:before{content:"\0025cf  "}.lst-kix_8e9je34qm6o7-5>li:before{content:"\0025a0  "}.lst-kix_sbdbv2a1ucvm-3>li:before{content:"\0025cf  "}ul.lst-kix_df6fn36a3u4o-7{list-style-type:none}ul.lst-kix_df6fn36a3u4o-6{list-style-type:none}.lst-kix_sbdbv2a1ucvm-4>li:before{content:"\0025cb  "}.lst-kix_8e9je34qm6o7-1>li:before{content:"\0025cb  "}ul.lst-kix_df6fn36a3u4o-8{list-style-type:none}ul.lst-kix_df6fn36a3u4o-3{list-style-type:none}ul.lst-kix_df6fn36a3u4o-2{list-style-type:none}ul.lst-kix_df6fn36a3u4o-5{list-style-type:none}.lst-kix_8e9je34qm6o7-2>li:before{content:"\0025a0  "}ul.lst-kix_df6fn36a3u4o-4{list-style-type:none}.lst-kix_8e9je34qm6o7-6>li:before{content:"\0025cf  "}ul.lst-kix_o3c3kswyzx42-0{list-style-type:none}ul.lst-kix_o3c3kswyzx42-1{list-style-type:none}ul.lst-kix_o3c3kswyzx42-2{list-style-type:none}.lst-kix_9lbma9vfugut-1>li:before{content:"\0025cb  "}ul.lst-kix_o3c3kswyzx42-3{list-style-type:none}ul.lst-kix_o3c3kswyzx42-4{list-style-type:none}.lst-kix_9lbma9vfugut-2>li:before{content:"\0025a0  "}ul.lst-kix_o3c3kswyzx42-5{list-style-type:none}ul.lst-kix_o3c3kswyzx42-6{list-style-type:none}.lst-kix_9lbma9vfugut-6>li:before{content:"\0025cf  "}.lst-kix_spmomcke4os8-1>li:before{content:"\0025cb  "}ul.lst-kix_df6fn36a3u4o-1{list-style-type:none}ul.lst-kix_df6fn36a3u4o-0{list-style-type:none}.lst-kix_9lbma9vfugut-5>li:before{content:"\0025a0  "}.lst-kix_spmomcke4os8-4>li:before{content:"\0025cb  "}.lst-kix_spmomcke4os8-5>li:before{content:"\0025a0  "}ol.lst-kix_i6pzozb09tpp-0{list-style-type:none}.lst-kix_spmomcke4os8-8>li:before{content:"\0025a0  "}.lst-kix_bmdfdiffj318-8>li:before{content:"-  "}ul.lst-kix_x68yhsmhn47y-8{list-style-type:none}ul.lst-kix_x68yhsmhn47y-7{list-style-type:none}ul.lst-kix_x68yhsmhn47y-6{list-style-type:none}ul.lst-kix_x68yhsmhn47y-5{list-style-type:none}ul.lst-kix_x68yhsmhn47y-4{list-style-type:none}.lst-kix_zigfdtz9pu7t-4>li:before{content:"\0025cb  "}.lst-kix_z9041a6ln04m-8>li:before{content:"\0025a0  "}.lst-kix_bmdfdiffj318-0>li:before{content:"-  "}ul.lst-kix_x68yhsmhn47y-3{list-style-type:none}ul.lst-kix_x68yhsmhn47y-2{list-style-type:none}.lst-kix_zigfdtz9pu7t-8>li:before{content:"\0025a0  "}.lst-kix_z9041a6ln04m-4>li:before{content:"\0025cb  "}ul.lst-kix_x68yhsmhn47y-1{list-style-type:none}.lst-kix_bmdfdiffj318-4>li:before{content:"-  "}ul.lst-kix_x68yhsmhn47y-0{list-style-type:none}.lst-kix_h3e2fv4cmf9v-6>li:before{content:"\0025cf  "}.lst-kix_5jnfbo9vknc3-4>li:before{content:"\0025cb  "}ul.lst-kix_qza8dbp12114-1{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-8{list-style-type:none}ul.lst-kix_qza8dbp12114-0{list-style-type:none}.lst-kix_z9041a6ln04m-0>li:before{content:"\0025cf  "}.lst-kix_df6fn36a3u4o-1>li:before{content:"\0025cb  "}ul.lst-kix_y4sl13ifkgmm-7{list-style-type:none}ul.lst-kix_qza8dbp12114-3{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-6{list-style-type:none}ul.lst-kix_qza8dbp12114-2{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-5{list-style-type:none}ul.lst-kix_qza8dbp12114-5{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-4{list-style-type:none}ul.lst-kix_qza8dbp12114-4{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-3{list-style-type:none}ul.lst-kix_qza8dbp12114-7{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-2{list-style-type:none}ul.lst-kix_qza8dbp12114-6{list-style-type:none}ul.lst-kix_qza8dbp12114-8{list-style-type:none}.lst-kix_df6fn36a3u4o-5>li:before{content:"\0025a0  "}.lst-kix_h3e2fv4cmf9v-2>li:before{content:"\0025a0  "}.lst-kix_5jnfbo9vknc3-0>li:before{content:"\0025cf  "}ol.lst-kix_k8lu2ylie4bt-8.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-8 0}ul.lst-kix_e9lsjgl3agqq-0{list-style-type:none}.lst-kix_sbdbv2a1ucvm-7>li:before{content:"\0025cb  "}ul.lst-kix_e9lsjgl3agqq-1{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-2{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-3{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-4{list-style-type:none}ul.lst-kix_y4sl13ifkgmm-1{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-5{list-style-type:none}.lst-kix_6168y9xo6jas-8>li:before{content:"\0025a0  "}.lst-kix_zigfdtz9pu7t-0>li:before{content:"\0025cf  "}ul.lst-kix_y4sl13ifkgmm-0{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-6{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-7{list-style-type:none}ul.lst-kix_e9lsjgl3agqq-8{list-style-type:none}ol.lst-kix_k8lu2ylie4bt-5.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-5 0}ul.lst-kix_6168y9xo6jas-1{list-style-type:none}ul.lst-kix_6168y9xo6jas-2{list-style-type:none}ul.lst-kix_6168y9xo6jas-0{list-style-type:none}.lst-kix_92zwylia2gw-1>li:before{content:"\0025cb  "}.lst-kix_92zwylia2gw-5>li:before{content:"\0025a0  "}ul.lst-kix_6168y9xo6jas-5{list-style-type:none}ul.lst-kix_6168y9xo6jas-6{list-style-type:none}.lst-kix_tt0bruxtd04w-7>li:before{content:"\0025cb  "}ul.lst-kix_6168y9xo6jas-3{list-style-type:none}ul.lst-kix_6168y9xo6jas-4{list-style-type:none}.lst-kix_x68yhsmhn47y-5>li:before{content:"\0025a0  "}.lst-kix_a8qujuk25xw2-1>li:before{content:"\0025cb  "}.lst-kix_i6pzozb09tpp-3>li:before{content:"-  "}.lst-kix_k8lu2ylie4bt-6>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-6}.lst-kix_zhlpi08mbuyv-6>li:before{content:"-  "}.lst-kix_k8lu2ylie4bt-1>li{counter-increment:lst-ctn-kix_k8lu2ylie4bt-1}.lst-kix_tt0bruxtd04w-3>li:before{content:"\0025cf  "}.lst-kix_o3c3kswyzx42-2>li:before{content:"\0025a0  "}ol.lst-kix_k8lu2ylie4bt-6.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-6 0}.lst-kix_b71z0bwzk1nz-7>li:before{content:"\0025cb  "}.lst-kix_jxj988oac1jn-7>li:before{content:"\0025cb  "}.lst-kix_b71z0bwzk1nz-3>li:before{content:"\0025cf  "}.lst-kix_zhlpi08mbuyv-2>li:before{content:"-  "}li.li-bullet-0:before{margin-left:-18pt;white-space:nowrap;display:inline-block;min-width:18pt}.lst-kix_v6i4vcxz3xlh-7>li:before{content:"\0025cb  "}.lst-kix_jxj988oac1jn-3>li:before{content:"\0025cf  "}.lst-kix_84l1nt15bcm1-3>li:before{content:"\0025cf  "}ol.lst-kix_k8lu2ylie4bt-7.start{counter-reset:lst-ctn-kix_k8lu2ylie4bt-7 0}.lst-kix_o3c3kswyzx42-6>li:before{content:"\0025cf  "}.lst-kix_84l1nt15bcm1-7>li:before{content:"\0025cb  "}ul.lst-kix_6168y9xo6jas-7{list-style-type:none}ul.lst-kix_6168y9xo6jas-8{list-style-type:none}.lst-kix_v6i4vcxz3xlh-3>li:before{content:"\0025cf  "}ol{margin:0;padding:0}table td,table th{padding:0}.c9{color:#595959;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Roboto";font-style:normal}.c19{padding-top:20pt;padding-bottom:6pt;line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c14{padding-top:18pt;padding-bottom:6pt;line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.c2{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left;height:11pt}.c4{color:#595959;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c22{margin-left:18pt;padding-top:3pt;padding-bottom:4pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c12{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:16pt;font-family:"Arial";font-style:normal}.c1{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c15{margin-left:18pt;padding-top:3pt;padding-bottom:0pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c5{color:#000000;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c3{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c21{padding-top:4pt;padding-bottom:0pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c17{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-family:"Arial";font-style:normal}.c23{color:#000000;text-decoration:none;vertical-align:baseline;font-family:"Arial";font-style:normal}.c11{padding-top:0pt;padding-bottom:0pt;line-height:1.15;text-align:left}.c18{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#595959;text-decoration:underline}.c8{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#1155cc;text-decoration:underline}.c27{background-color:#ffffff;max-width:468pt;padding:72pt 72pt 72pt 72pt}.c24{vertical-align:baseline;font-size:11pt;font-style:normal}.c7{color:inherit;text-decoration:inherit}.c26{margin-left:108pt;padding-left:0pt}.c10{padding:0;margin:0}.c20{font-weight:400;font-family:"Roboto"}.c6{margin-left:36pt;padding-left:0pt}.c16{margin-left:72pt;padding-left:0pt}.c0{font-weight:700}.c28{font-size:20pt}.c13{font-size:14pt}.c25{height:11pt}.title{padding-top:0pt;color:#000000;font-size:26pt;padding-bottom:3pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:15pt;padding-bottom:16pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:20pt;color:#000000;font-size:20pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:18pt;color:#000000;font-size:16pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:16pt;color:#434343;font-size:14pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:14pt;color:#666666;font-size:12pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}</style><div class="c27"><h1 class="c19" id="h.7itzacxkx1m6"><span class="c17 c28">WebPerf WG F2F June 2019 Minutes</span></h1><p class="c2"><span class="c1"></span></p><p class="c21"><span class="c5 c0"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.7itzacxkx1m6">WebPerf WG F2F June 2019 Minutes</a></span><span class="c5 c0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c5 c0"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.7itzacxkx1m6">1</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.6x19q6m3dnhx">Noam Helfman - Microsoft: Gaps in web perf metrics: navigation, resource loading, interactivity</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.6x19q6m3dnhx">1</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.yq1v7vwqt97a">Nic Jansma - Akamai: Akamai and WebPerf</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.yq1v7vwqt97a">2</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.un5zd34nxonb">Gilles Dubuc - Wikimedia: Web Performance</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.un5zd34nxonb">4</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.i8acbewa2ch">Steve Bourgon and Nolan Lawson - Salesforce</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.i8acbewa2ch">5</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.m928xx169l22">Thomas Kelly - Shopify</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.m928xx169l22">7</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.ku5jwn4ne97q">Amiya Gupta - Microsoft: Identifying ad interference with page load</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.ku5jwn4ne97q">9</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.z4f4f7l39quk">Beng Eu and Warren Godone Marsesca - WebPerf @ Google Ads</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.z4f4f7l39quk">11</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.x0ih8vnl6qwo">Ulan Degenbaev - Google: JavaScript memory API</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.x0ih8vnl6qwo">14</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.ptau5ck3jdlk">Scheduling APIs</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.ptau5ck3jdlk">16</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.oluroz2qrd9a">CPU reporting</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.oluroz2qrd9a">18</a></span></p><p class="c15"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.mdnqofs1n3yc">Metrics for Single Page Apps</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.mdnqofs1n3yc">19</a></span></p><p class="c22"><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.ss0pq2xgjdg4">Group processes</a></span><span class="c1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="c1"><a class="c7" href="https://docs.google.com/document/d/e/2PACX-1vQ8mmZftJCz6SE9Fa26Zqi2KGwtWYr0HTiH1_XxHEE50Gz4NdYpMvoKQs2Gqb3iE-CKv32vmaSQ3kDt/pub#h.ss0pq2xgjdg4">22</a></span></p><h2 class="c14" id="h.xm9btq6ueyhb"><span class="c12">Participants</span></h2><p class="c3"><span class="c1">Ilya Grigorik, Tim Dresser, Nicolás Peña Moreno, Sam Burnett, Staphany Park, Yoav Weiss, Steven Bougon, Andrew Comminos, Thomas Kelly, Todd Reifsteck, Philippe Le Hegaret, Ulan Degenbaev, Nic Jansma, Gilles Dubuc, Ben Kelly, Noam Helfman, Nathan Schloss, Ryosuke Niwa, Wooseok Jeong, Warren Godone Maresca, Beng Eu, Scott Haseley, Benjamin De Kosnik, Steve Souders, Amiya Gupta, Philipp Weis, Patrick Meenan, Nolan Lawson, Nicole Sullivan, Vikram Shankar, Andrew Clark</span></p><p class="c2"><span class="c1"></span></p><h2 class="c14" id="h.6x19q6m3dnhx"><span class="c12"><b>Gaps in web perf metrics</b>: navigation, resource loading, interactivity - Noam Helfman (Microsoft Excel)</span></h2><p class="c3"><span class="c8 c0 c13"><a class="c7" href="https://www.google.com/url?q=https://drive.google.com/file/d/1-P_UrqWH03pt0Uo_IUwmP1pRj_JV2lYb/view&amp;sa=D&amp;source=editors&amp;ust=1623069033895000&amp;usg=AOvVaw2-ZtZeux9b-0bIWFVPT4lN">Slides</a></span><span class="c0 c13">, </span><span class="c8 c0 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D1341&amp;sa=D&amp;source=editors&amp;ust=1623069033896000&amp;usg=AOvVaw02brw7Wyppc0Vffzy2HBg3">video</a></span></p><p class="c3"><span class="c5 c0">Talk</span></p><ul class="c10 lst-kix_sbdbv2a1ucvm-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Works on Excel online - a complex web app</span></li><li class="c3 c6 li-bullet-0"><span>Navigation Timing - </span><span>missing timing when opening a new tab</span></li></ul><ul class="c10 lst-kix_sbdbv2a1ucvm-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">Take a timestamp on the “origin tab” and pass it around to the target frame. </span></li><li class="c3 c16 li-bullet-0"><span class="c1">Can get complicated when redirects are involved</span></li></ul><ul class="c10 lst-kix_sbdbv2a1ucvm-0"><li class="c3 c6 li-bullet-0"><span class="c1">Resource Timing - missing “loaded from cache” boolean and “resource processing” timings</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Paint timings - when did the user see paint operations?</span></li></ul><ul class="c10 lst-kix_sbdbv2a1ucvm-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">Discussion</span></li></ul><ul class="c10 lst-kix_sbdbv2a1ucvm-2 start"><li class="c3 c26 li-bullet-0"><span class="c1">Element Timing is likely to address that</span></li><li class="c3 c26 li-bullet-0"><span class="c1">Frame Timing can help the “long frame” case</span></li></ul><ul class="c10 lst-kix_sbdbv2a1ucvm-0"><li class="c3 c6 li-bullet-0"><span class="c1">Long tasks - need to find long tasks that resulted in missing frames and be able to attribute that</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Memory - Need to figure out GC events, duration, frequency, etc. Also interested in JS heap</span></li></ul><p class="c3"><span class="c5 c0">Questions</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: what about mobile?</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: They use native apps, so presumably use APIs available there. </span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: what about paint timing?</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: we want per-frame information.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Element Timing exposes the paint time of new elements.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: we also want long tasks caused by JS.</span></p><p class="c3"><span class="c1">Can use the long tasks API to look at that, but attribution sucks.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: hopefully in the future we can use the sampling profiler to expose better attribution.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: transfer size should already be available.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: handling redirects is very tricky, need to pass on the timestamps, no standard way.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: re cached boolean, you can look at transfer size, but need some heuristics around that.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: heuristic we use is time (if it’s very short, very likely from cache).</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: yes but there can also be long cache reads.</span></p><p class="c3"><span class="c0">Ben</span><span class="c1"><b></b>: also, service worker could be serving from cache, but could take time to serve it.</span></p><h2 class="c14" id="h.yq1v7vwqt97a"><span class="c12">Akamai and WebPerf - Nic Jansma (Akamai)</span></h2><p class="c3"><span class="c8 c0 c13"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1JbBmn6OKLCPWwiLrSU6QvJm2jwtbbGTTozOGtNttWxI/edit?usp%3Dsharing&amp;sa=D&amp;source=editors&amp;ust=1623069033902000&amp;usg=AOvVaw2__PQxHav_2ieWzMfV3QLX">Slides</a></span><span class="c13">, </span><span class="c8 c0 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D2364&amp;sa=D&amp;source=editors&amp;ust=1623069033902000&amp;usg=AOvVaw3vqDeT4owMfoZg23r3WTf6">video</a></span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Talk</span></p><p class="c3"><span class="c1">Akamai is a CDN which does media delivery, performance, security, monitoring. mPulse is a real user monitoring product which can aggregate to a beacon. It measures more than a billion user experiences per day. It currently uses NavTiming, ResourceTiming, UserTiming, PerfTimeline, LongTasks, PaintTiming, EventTiming, ReportingAPI, etc.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Some challenges:</span></p><ul class="c10 lst-kix_jf43zqpqkez-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">We use a non-blocking async loader, so it is 2.5kb to avoid affecting onload (want to avoid affecting onload, but that means possibly loading after onload).</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Once loaded, we want to be able to look back in time to collect everything.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Customers may not have expertise, so want automatic collection and providing basic information.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">We need to be able to explain the why and how to fix the problems.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">SPAs are not covered by NavTiming alone. We use hacks right now (MutationObserver + ResourceTiming), but it’s not performant and not standard.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Synthetic tests have access to low level data but RUM does not, so hard to compare (example: Time to Interactive).</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Cannot trust the numbers</b>: browser differences, outliers.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">There are lots of browser bugs, and some people use legacy browsers (need to fall back to less reliable hacks).</span></li></ul><p class="c3"><span class="c1">Top issues for ResourceTiming:</span></p><ul class="c10 lst-kix_e9lsjgl3agqq-0 start"><li class="c3 c6 li-bullet-0"><span class="c1"><b>Better reporting</b>: initiatorType needs to be improved, and we’d like content type, resource processing time, and response code for the resource request.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Better visibility</b>: we want to see non-200 responses, TAO should be made a subset of CORS (to get more information), no insight into in-flight requests, incomplete insight for multi-fetches…</span></li></ul><p class="c3"><span class="c1">Top other issues</span></p><ul class="c10 lst-kix_aglivdlbfii-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">We’d like for iframes to be able to bubble information upwards.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">LongTasks should have better attribution.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">SPA Monitoring is very hard.</span></li></ul><p class="c3"><span class="c1"><b>Love the new specs</b>: long tasks, event timing, element timing, layout stability, JS self profiling, Javascript Memory API.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0 c5">Links:</span></p><p class="c11 c25"><span class="c9"></span></p><ul class="c10 lst-kix_y4sl13ifkgmm-0 start"><li class="c11 c6 li-bullet-0"><span class="c18 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/8&amp;sa=D&amp;source=editors&amp;ust=1623069033905000&amp;usg=AOvVaw2LM-I7sd3qmPizqe5T2qer">Improved initiatorType</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18 c20 c24"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/203&amp;sa=D&amp;source=editors&amp;ust=1623069033905000&amp;usg=AOvVaw15EmBbOcFIsLQWJOoZYmyB">Content Type</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/133&amp;sa=D&amp;source=editors&amp;ust=1623069033906000&amp;usg=AOvVaw20t9hbdnSD7_AC8X2Zhhc-">Resource Processing Time</a></span></li><li class="c6 c11 li-bullet-0"><span class="c18 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/90&amp;sa=D&amp;source=editors&amp;ust=1623069033906000&amp;usg=AOvVaw1N9tkR6ktBoFx2RBHvjAsO">Response Code</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18 c24 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/12&amp;sa=D&amp;source=editors&amp;ust=1623069033907000&amp;usg=AOvVaw2c6FgYIaOABqgoZeIOhMml">Including non-200 responses</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18 c24 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/178&amp;sa=D&amp;source=editors&amp;ust=1623069033907000&amp;usg=AOvVaw0wv695WBq00K4_EqOKM0vq">TAO as a subset of CORS</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/137&amp;sa=D&amp;source=editors&amp;ust=1623069033908000&amp;usg=AOvVaw0u_zjGbMsk5O5RiYjsKPFi">In-Flight Requests</a></span><span class="c9">&nbsp;(SPA monitoring, Interactive calculations)</span></li><li class="c11 c6 li-bullet-0"><span class="c18 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/21&amp;sa=D&amp;source=editors&amp;ust=1623069033908000&amp;usg=AOvVaw2gX6RxhgwZ_d0mEYqhi5dZ">Multi-request fetches</a></span><span class="c9">&nbsp;(redirects)</span></li><li class="c11 c6 li-bullet-0"><span class="c18 c20"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/resource-timing/issues/210&amp;sa=D&amp;source=editors&amp;ust=1623069033909000&amp;usg=AOvVaw3ksMWKPSTdv_DYfQ-2QO1u">Cross-Origin IFRAME opt-in</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/performance-timeline/issues/86&amp;sa=D&amp;source=editors&amp;ust=1623069033909000&amp;usg=AOvVaw1tTBgR0LPaRMpgry7M3J_T">Performance Timeline Bubbles</a></span></li><li class="c11 c6 li-bullet-0"><span class="c18"><a class="c7" href="https://www.google.com/url?q=https://github.com/w3c/longtasks/issues/42&amp;sa=D&amp;source=editors&amp;ust=1623069033910000&amp;usg=AOvVaw3NioxSlQuftvUivI2ucYu0">LongTasks better attribution</a></span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Questions</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: are the bugs covered by web platform tests?</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: I’ve filed several of the bugs. A lot are fixed. We can do a better job at keeping track.</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: is there someplace where it’s not true that it would be good to ‘look back in time’ when the analytics script loaded and see past metrics?</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: for ResourceTiming we can, but want to make sure this is considered for anything going forward. We want metrics to be buffered.</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: what about long tasks?</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: Correct, so we need to inject script early to start collecting data ahead of time.</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: In ResourceTiming, for cross-origin resources the time includes queueing time, which is very misleading. It does not seem like a security issue to break those two apart.</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: Is there an issue for that on the RT repo?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: not sure if there is an issue in GitHub, may be in the backlog, not L2 blocker.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: we have a proposal for header registration for long tasks.</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: we have to initiate the PerformanceObserver in the snippet and customers don’t put it at the top. And there’s nothing we can do about that.</span></p><p class="c3"><span class="c0">Nicolás</span><span class="c1"><b></b>: the alternative is to always measure so we can have a buffer for when it is requested.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: That doesn’t work for expensive metrics, e.g. longtasks may be expensive to measure.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: will be more expensive with attribution.</span></p><h2 class="c14" id="h.un5zd34nxonb"><span class="c12">Gilles Dubuc - Wikimedia: Web Performance</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1OBXx6DGu-w3-dwRB4OQPymH943nFQBFiaW2bMO1yJPA/edit?usp%3Dsharing&amp;sa=D&amp;source=editors&amp;ust=1623069033913000&amp;usg=AOvVaw12OadgIz3ON5JdxbIR5kkY">Slides</a></span><span class="c13">, </span><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D3685&amp;sa=D&amp;source=editors&amp;ust=1623069033913000&amp;usg=AOvVaw3niZ9h9-ojiKQhxUBDkCCu">video</a></span></p><p class="c3"><span class="c5 c0">Talk</span></p><p class="c3"><span class="c1">We use everything except for long tasks (for reasons discussed before). We have public RUM dashboards and do perf regression monitoring. Some top suggestions:</span></p><ul class="c10 lst-kix_x68yhsmhn47y-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">We want to focus on other things than initial page render!</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Attribution is key to help figure out what the problems are.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Observer patterns all need buffering</b>: we do not want to inject JS in the head. Headers are OK.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>First render point hint</b>: browser needs to process more DOM nodes than needed for its first paint. Thus, it might be useful for developer to provide the browser with a hint of a reasonable cutoff point. Maybe have an HTML tag for the cutoff point?</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Need to include JS errors via the Reporting API. This would save websites from using heavy client-side libraries like Sentry.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>effectiveConnectionType buckets should be updated</b>: 4G captures too much, so we should add another top tier.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Custom times in User Timing (already in L3).</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Questions</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: You talked about categories, can you clarify?</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: we need to know where long tasks come from (rendering, etc.)</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: can you clarify about the Reporting API?</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: right now we need to report JS errors manually, so load a library to do that. This should be done by the Reporting API.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: +1 to avoid using expensive JS libraries.</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: buffering can be an issue here as well.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: it is an issue for ReportingObserver, but not for reports that are beaconed to an endpoint.</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: right now, if the onerror handler gets installed too late, you’re potentially missing errors.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: we recently added DeprecationReport. Someone should aggregate and put in a standard.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: maybe we should have header/HTML registration and ideally you can collect in a single endpoint.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: have you looked at the RTT and downlink data?</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: no I don’t think so, we will.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Also, User Timing L3 should give you what you need with regard to custom entries.</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: memory pressure or device info would be useful?</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: yea, can’t derive much right now from UA string, for instance battery level. We want something that tells us how powerful the device is right now.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: UA string is likely to lose entropy in the near future, at least by default. does device memory give a good enough correlation to CPU?</span></p><p class="c3"><span class="c0">Benjamin/Gilles</span><span class="c1"><b></b>: no, need both.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: so we want slow/medium/fast. Hard to figure out useful grade that does not leak a lot of information.</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: even something in coarse buckets would be good to know.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: We need coarse enough buckets to be barely useful, to avoid adding unneeded entropy</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: Need to build those buckets from data</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: bucketing is hard, maybe use some sort of baselining.</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: We can run a benchmark in a worker, but want to know if improvements are due to website improvement or device improvement over a long period.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Can we expose CPU cycles?</span></p><p class="c3"><span class="c0">Pat</span><span class="c1"><b></b>: Not enough data as there’s GPU, I/O, etc. also how many of these benchmarks do we want?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: can’t run these benchmarks on the user device, as we’d drain their battery . We need to collect that data passively</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: Unless we expose something on that front, that’s what devs are currently doing</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: &nbsp;For images, that what sites used to do: fetch a known sized image to determine the bandwidth.</span></p><p class="c3"><span class="c0">Pat</span><span class="c1"><b></b>: For fingerprinting/entropy, it might be fine to expose as long as developers can already actively measure it </span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Maybe. It also has to be active rather than passive fingerprinting. Sites need to explicitly ask for it.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: also sensitive to timing attacks.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: we should gather use cases and understand how people are solving them.</span></p><h2 class="c14" id="h.i8acbewa2ch"><span class="c12">Steve Bourgon and Nolan Lawson (Salesforce)</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1vmbs-WCHwPTsu1Osl4UFMonQyY2LJ8FNKAVaVojKOk8/edit?usp%3Dsharing&amp;sa=D&amp;source=editors&amp;ust=1623069033922000&amp;usg=AOvVaw1a_S4u2XUw7uTs6fMM8jxM">Slides</a></span><span class="c13">, </span><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D5108&amp;sa=D&amp;source=editors&amp;ust=1623069033922000&amp;usg=AOvVaw2S4S0pUFi_Yw9syoELrPIP">video</a></span></p><p class="c3"><span class="c5 c0">Talk</span></p><p class="c3"><span class="c1">Salesforce is a Web application (SPA). We transitioned from server-rendered HTML 5 years ago, and we are embracing web components. Performance is key to us. It is a metadata-driven app: need to dynamically add/remove components.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1"><b>Current Perf API usage</b>: high res timing, perf timeline, Resource/Nav/User Timing, beacon, page visibility. We have some in-process, some we do not use at all.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Suggestions:</span></p><ul class="c10 lst-kix_b71z0bwzk1nz-0 start"><li class="c3 c6 li-bullet-0"><span class="c1"><b>Main thread metrics in RUM</b>: distribution of how much is loading, scripting, rendering, layout, etc. This would help us know where we should optimize.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Browser health metrics</b>: we use Octane to measure machine health, and it has a direct correlation with TTI, but can’t use in RUM.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Native TTI calculation. It is very painful to compute manually with existing APIs.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>GC hinting</b>: GC can occur at bad times. We can hint when we have idle time: window.requestSystemCleanup().</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Isolated frames</b>: allow same origin frames to request themselves to be out of process. This helps hide and prerender full pages.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Memory leak detection</b>: mark two points that should have approx. same memory, and then measure the delta.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>SPA navigation</b>: many events are only available upon navigation (for example, FCP). It would be great if we can reset these primitives when we are about to fully redraw a page. LCP (Largest Contentful Paint) is promising but also want to be able to reset it.</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Questions:</span></p><p class="c3"><span class="c0">Pat</span><span class="c1"><b></b>: SPA navigations are also different from single-page navigations. E.g. no cleanup for inflight requests. Something broader to think about as we look at SPA navigations.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Can cancellable fetches help?</span></p><p class="c3"><span class="c0">Pat</span><span class="c1"><b></b>: Only if you initiated those requests with fetch. Not always the case.</span></p><p class="c3"><span class="c0">Nolan</span><span class="c1"><b></b>: if there is XHR when we are navigating, we mark it as an outlier.</span></p><p class="c3"><span class="c0">Noam</span><span><b></b>: You mentioned out-of-process iframes. Chrome already supports cross-origin to be on </span><span>different process</span><span class="c1">, so is the suggestion for same origin?</span></p><p class="c3"><span class="c0">Steven Bougon</span><span class="c1"><b></b>: correct.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Currently it’s cross-site iframes that go into a separate process, but not same-site cross-origin ones. Maybe we can add that to the Cross-Origin-Opener-Policy proposals to enable a site to request isolation from same-origin.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: would need to disable document.domain.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Sure, but a site can opt-in to disabling document.domain with a Feature Policy.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, you’d need to set that in a header. Also, no access to any sync API that touches the opener would have to be disabled. We discussed COOP in the context of Spectre mitigations, but they may work for this as well. Maybe we can have header / iframe attribute.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: for browsers without site isolation, how hard would it be to make that work?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: need full site isolation because that iframe can contain other iframes.</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: you are not using the long tasks API?</span></p><p class="c3"><span class="c0">Steve Bougon</span><span class="c1"><b></b>: yea, because of attribution. We do not know where the tasks are coming from.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: I was hoping it would be useful for regression detection.</span></p><p class="c3"><span class="c0">Steve Bougon</span><span class="c1"><b></b>: we already have some regression detection. We’d love to know where the long tasks are coming from.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: so even to use it for regression detection, there needs to be some attribution, esp. with how complex Salesforce is.</span></p><p class="c3"><span class="c0">Nolan</span><span class="c1"><b></b>: not sure it captures style and layout?</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: it does capture style and layout. We fixed the spec.</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: everything is just reported as unknown. We do find it really useful, even though we don’t know where it comes from.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: for GC API, everyone will start calling it and it would not be a good signal. We already try to do GC when the webpage becomes idle, so if it’s frequent problem then maybe there is some improvement to be done.</span></p><p class="c3"><span class="c0">Steve Bougon</span><span><b></b>: yes, some customers add and remove components, memory usage is through the roof.</span><span class="c1">&nbsp;And we don’t want to force a GC, just a hint to the browser.</span></p><p class="c2"><span class="c1"></span></p><h2 class="c14" id="h.m928xx169l22"><span class="c12">Thomas Kelly (Shopify)</span></h2><p class="c3"><span class="c8"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1zuOAnd_JnVD61TaPgdCFi_vLDc6kI24m-iDasay1s-4/edit?usp%3Dsharing&amp;sa=D&amp;source=editors&amp;ust=1623069033928000&amp;usg=AOvVaw0yhiRd7Rn2qlbmvIUDmmfk">Slides</a></span><span>, </span><span class="c8"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D6334&amp;sa=D&amp;source=editors&amp;ust=1623069033928000&amp;usg=AOvVaw3OXuLHP60QRLqIF7qfyEfa">video</a></span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Presentation</span></p><p class="c3"><span class="c1">Performance is key. When Thomas started, quite different from using speedcurve and now, collecting data from all the stores, thanks to Lighthouse. Ability to dive deep through issue affecting all merchants.</span></p><p class="c3"><span class="c1">Shopify is a CMS in a way. Online stores can be anything, so huge variance from merchant to merchant. </span></p><p class="c3"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 468.00px;"><img alt="" src="./WebPerf WG F2F June 2019 Minutes_files/06AB6A4C-6590-460E-9F7C-A6E74E9F9836.jpeg" style="width: 624.00px;<b> height</b>: 468.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></p><p class="c3"><span class="c1">Online stores are built around themes, which are very fast out of the box. But get slower over time when folks add things. So need to automate optimizations so that folks don’t have to care about them.</span></p><p class="c3"><span class="c1">Things need to be updated as issues are found, like the Chrome team.</span></p><p class="c3"><span class="c1">The biggest problems:</span></p><ul class="c10 lst-kix_6168y9xo6jas-0 start"><li class="c3 c6 li-bullet-0"><span class="c1"><b>Images</b>: wrong formats being served (WebP, fallback to universal format). Still a % of users need JPG or PNG.</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Apps and Extensions</b>: Apps can be installed in all storefront. Hard to optimize the Critical Path. Can we defer app ? How to differentiate core apps and installed apps. Some apps need to use Jquery, resulting in duplicate dependencies</span></li></ul><ul class="c10 lst-kix_6168y9xo6jas-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">Import maps may be helpful here, to enable them to coalesce those duplicates</span></li></ul><ul class="c10 lst-kix_6168y9xo6jas-0"><li class="c3 c6 li-bullet-0"><span class="c1"><b>RUM Library</b>: like Akamai and Boomerang app, it’s really hard to get RUM. Have an app, but we need to update it with latest WebPerf APIs. Should we (shopify) use Boomerang ? Deploying to 800K stores is challenging in terms of scale</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1"><b>ElementTiming</b>: this API is very interesting, but tied to a specific HTML element. LCP may be a good way to get that information for users that don’t add the attribute.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Layout shift can help with images when completely implemented. </span></p><p class="c3"><span class="c1">Client Hints for responsive images would also be great once implemented across browsers.</span></p><p class="c3"><span class="c1"><b>About WebP</b>: is there a tradeoff between CPU and network ? That’s an unresolved question for us still.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">Experience with Web Perf Group</span><span class="c1"><b></b>: wanted to introduce myself, I was late in the game, lots happened in 2017/2018. Shopify is involved in the Payment WG. My team and I are having challenges using the new APIs, learning from the specs, so wondering how can we bring up to speed new members, how to onboard new members. Maybe a mentorship ? Pairing with someone on issues in the repo ?</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1"><b>When it comes time to test new APIs</b>: we would like to try ElementTiming with Origin Trial, but we have 500K domains.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Questions</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Are the different domains for Origin Trials *.shopify.com</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: no. (“sellmydog.com” from Todd :-) )</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Around images, is there a reason why an upload process of images could not reformat images? or provide a hint?</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: We have an open lighthouse issue on this. It’s hard to know which images should be PNGs and which ones shouldn’t. We use transparency as a way to tell them apart.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: You can use webp for that in supporting browsers.</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: Yeah, but ~10% of the traffic is still going to be requesting PNGs.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Issue with signaling. There are 2 issues: surfacing the problem with requested formats and the upload process which could fix it in this case.</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: it’s up to us to fix the automation and the upload process.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: it’s not just the size. Lighthouse is a tool for automation but not RUM</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Feature policy might help: could look into bit per pixel, and above a threshold, would tell you to stop.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: is there an API we haven’t exposed yet ?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Would you turn a feature policy which would disable the download of images that are too large?</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: yes, in the editor or as a reporting-only</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Current FPs may have different ratios per file type</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: So need to make it configurable?</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: There’s an opportunity. At Google, we built a wordpress team to look into CMS. They have the same problem: apps are installed and we don’t know their perf due to server-side extensions and plugins. So, we went to WP and annotated it so we now know that one extension cost X MB. Maybe there is a shared format for these annotations so we can see them in devtools ?</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: looking into something like that right now, with user-timing and lighthouse</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: could we use server-timing?</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: might be interesting use case for this (ST). We see this around all the CMS. For instance, I could instance a gallery extension, which would inject the 5th version of JQuery.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Open questions on how to standardize it and enforce the standard.</span></p><p class="c2"><span class="c1"></span></p><h2 class="c14" id="h.ku5jwn4ne97q"><span class="c12">Identifying ad interference - Amiya Gupta (Microsoft News) </span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://1drv.ms/p/s!AieUMe5bQRWh8dNh2uqgUrMFw0U49A?e%3DYlXsj4&amp;sa=D&amp;source=editors&amp;ust=1623069033934000&amp;usg=AOvVaw3Y7Y9OXTb5wsoxSzIAMQsS">Slides</a></span><span class="c13">, </span><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D8096&amp;sa=D&amp;source=editors&amp;ust=1623069033934000&amp;usg=AOvVaw1qq0_QhRRR7B4Hv6c-Fa-W">video</a></span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Presentation</span></p><p class="c3"><span class="c1">Amiya works at microsoft News. MSN.com is monetized via ads, which add these challenges:</span></p><ul class="c10 lst-kix_tt0bruxtd04w-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Display ads real time bidding</span></li><li class="c3 c6 li-bullet-0"><span class="c1">100K of unique ads / months</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Some ads have very bad performance</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Real time user feedback not enough</span></li><li class="c3 c6 li-bullet-0"><span class="c1">IE11</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Identify bad ads:</span></p><ul class="c10 lst-kix_u0fqahpsffbf-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Instrument pages</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Ad Analyser to find bad ads</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Use performance signals with ads telemetry</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Ad exchange involvement</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1"><b>Instrumentation</b>: We user RAF + User Timing API to add a marker. We log for 30 seconds, and it’s sampled. We get some useful metrics: Time To Interactive. Max Frame Length: longest frame in that page, helps us identify bad ads.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Amiya is showing some graphs using the data, identifying the bad partner. Now he is showing how he identified a partner and helped them remove the flash tracker, showing immediate perf gains.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1"><b>Downsides</b>: </span></p><ul class="c10 lst-kix_8e9je34qm6o7-0 start"><li class="c3 c6 li-bullet-0"><span class="c1"><b>RAF is a power consumer</b>: so we sample and cap logging duration</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Losing information because instrumentation started too late</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Lack of direct attribution</b>: we are using correlation to attibute</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Survivorship bias</b>: when measuring TTI/Long frame: some users leave the page, and so it skewing the numbers</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Questions</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: attribution - is that for cross-origin or same origin iframes?</span></p><p class="c3"><span class="c0">Amiya</span><span class="c1"><b></b>: Mostly same origin. Ad providers prefer friendly iframes</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: do the ad providers give an incentive to not be in the same iframe (vs 3rdParty)</span></p><p class="c3"><span class="c0">Amiya</span><span class="c1"><b></b>: not sure, but there’s probably some monetary value there, as they can get more info as a first party iframe</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: If the browser was offering frame timing, would that solve the use case for which you use rAF?</span></p><p class="c3"><span class="c0">Amiya</span><span class="c1"><b></b>: yes, it would solve our use-case, especially if it buffered</span></p><p class="c3"><span class="c0">Beng</span><span class="c1"><b></b>: Using a cross origin iframe at Google Ads shows a drop in revenue, because the ads are slower. We are trying to encourage them to use Sandboxed CO iframe. But it’s slower, so users click less</span></p><p class="c3"><span class="c0">Souders</span><span class="c1"><b></b>: why use RAF instead of Long task?</span></p><p class="c3"><span class="c0">Amiya</span><span class="c1"><b></b>: because of IE11 and lack of polyfill for LT.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Long frame were not reported by the Long Task API?</span></p><p class="c3"><span class="c0">Amiya</span><span class="c1"><b></b>: yes, we had some with many short tasks resulting in missed frames.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: The browser should try to schedule rendering between those short tasks</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: Not really shipped</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: should implementation and scheduler solve this? Or do we need separate reporting for Frame timing and LongTasks?</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: we need a solution the differentiates between long frame and LT reporting.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, there’s room for both. You can have LTs that don’t impact painting and frames.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: yeah, long tasks and frames also don’t have the same deadline</span></p><p class="c3"><span class="c0">Souders</span><span class="c1"><b></b>: Can you capture the missing data around early abandonment via an unload handler?</span></p><p class="c3"><span class="c0">Amiya</span><span class="c1"><b></b>: Maybe if we use sendBeacon there, but we’d still be missing reports</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: We need a reporting API that is registered early enough and reports if we never reached some point in the page.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: so a “dead man trigger” reporting API</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Something like that</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Maybe we can use paint events as the default target, that if not reached, the report gets fired </span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: What happened before the “dead man” trigger, that’s interesting to know</span></p><p class="c3"><span class="c0">Souders</span><span class="c1"><b></b>: looks like there is a general agreement that we can’t measure when a user abandon. Unload is not registered early enough ?</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Beacon is only 90% reliable</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: sometimes the browser gets killed</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: 3 to 4 problems: sometimes we can’t execute JS (and can’t register a DMT), but reporting API should help here. Crashes and OOM are specified in the reporting API </span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: It’s specified but not necessarily implemented/shipped.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: This space for RUM is critical. Laying out the phases, web developer solutions and holes would be helpful to determine if we need new specs.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: In some markets we see 20% of users that don’t reach FCP, and it’s potentially invisible to analytics.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: some users don’t even reach FCP (slow network regions)</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Even in the US, it’s in the low single digit %ages.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: maybe users clicked the wrong thing</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: That would’ve been consistent across regions</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: we can’t capture the abandonment ratio. We use FCP as the signal. It’s hard to understand the exact reason</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: We all looked into it, so there’s probably something interesting to expose there</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: could the browser save context and report it next session ?</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: that’s the use case for Network Error Logging</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: May introduce bias towards users that never registered NEL</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Yeah, but if registration happens on early enough bytes, that should be minimal</span></p><h2 class="c14" id="h.z4f4f7l39quk"><span class="c12">WebPerf @ Google Ads - Beng Eu and Warren Godone Marsesca (Google)</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=http://bit.ly/webperf-google-ads&amp;sa=D&amp;source=editors&amp;ust=1623069033942000&amp;usg=AOvVaw0YspIu5vJYne6skrmdkuy4">Slides</a></span><span class="c13">, </span><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D9745&amp;sa=D&amp;source=editors&amp;ust=1623069033942000&amp;usg=AOvVaw3bx6l9cgeuxSje8DbJdGxn">video</a></span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1"><b>adSpeed team</b>: trying to measure, understand and see the impact of ads on pages</span></p><p class="c3"><span class="c1">We measure on ALL pages which have ads.</span></p><p class="c3"><span class="c1">We are trying to make the speed of page with ads == the speed of page without ads :-)</span></p><p class="c3"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 468.00px;"><img alt="" src="./WebPerf WG F2F June 2019 Minutes_files/4BF048F6-67F5-4EB0-974C-378C02308BE7.jpeg" style="width: 624.00px;<b> height</b>: 468.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></p><p class="c3"><span class="c1">WebPerf API Usage:</span></p><ul class="c10 lst-kix_df6fn36a3u4o-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Most of them</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">How do we use them:</span></p><p class="c3"><span class="c1">We look at the speed of the device, and choose appropriate ads. Feeds to ML system. We use these APIs to reduce resource consumption. We try to lazy load ads via the IntersectionObserver.</span></p><p class="c3"><span class="c1"><b>Wishlist</b>: </span></p><ul class="c10 lst-kix_a8qujuk25xw2-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Raw CPU information</span></li><li class="c3 c6 li-bullet-0"><span class="c1">JS Benchmark like numbers (without running a JS benchmark)</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Tooling:</span></p><ul class="c10 lst-kix_84l1nt15bcm1-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">1000s A/B experiments. Detailed RUM on 0.5%. We collect data on the page and on the ads. So we can compare same page and different ads</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Available on Publisher Ads, so the publisher can see how slow or fast their ads are. It’s in Beta and Prod this week</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>We created a plugin for lighthouse</b>: gives recommendation specific for ad publisher.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Fast ads == higher revenue</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c5 c0">Challenges</span></p><p class="c3"><span class="c1">Measurement is easy, but using the data to improve is hard.</span></p><p class="c3"><span class="c1">As a user you want to see your content sooner, but don’t care about empty rectangles</span></p><p class="c3"><span class="c1"><b>As a advertiser</b>: capture user’s eye</span></p><p class="c3"><span class="c1"><b>As a publisher</b>: maximise ad revenue</span></p><p class="c3"><span class="c1"><b>As a tech provider</b>: balance satisfaction of users and advertiser ad publisher</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Real world ad publisher priorities:</span></p><p class="c3"><span class="c1">Content could load so fast that user scroll and don’t click ads</span></p><p class="c3"><span>Wishlist API</span><span class="c1"><b></b>: </span></p><ul class="c10 lst-kix_6k6ln47x41zf-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">deprioritize content loading but prioritize ads content. </span></li><li class="c3 c6 li-bullet-0"><span class="c1">API to indicate if the site cares more about performance or revenue</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Data experiment:</span></p><ul class="c10 lst-kix_16pzzom86drc-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">1ms timeout before each ad but we lose 1% of ad impression</span></li><li class="c3 c6 li-bullet-0"><span class="c1">1s network delay leads to 3% ad revenue (mobile web)</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Latency abhors a vacuum:</span></p><ul class="c10 lst-kix_uehujnp5bzt9-0 start"><li class="c3 c6 li-bullet-0"><span class="c1"><b>Lazy load ads</b>: 50% of the ads are never seen by users. </span></li><li class="c3 c6 li-bullet-0"><span class="c1">Lazy loading them is tough, as other scripts are hogging the main thread</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>isInputPending</b>: yield the thread. But no incentive to be a good citizen</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Tradeoff</b>: 1% ads revenue improvement but 2% slower: what do we do ?</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Paint/Element Timing of Pages</span></p><ul class="c10 lst-kix_qza8dbp12114-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Used to measure impact of ads loading</span></li><li class="c3 c6 li-bullet-0"><span class="c1">But:</span></li></ul><ul class="c10 lst-kix_qza8dbp12114-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">FCP because the dismiss button appears first</span></li><li class="c3 c16 li-bullet-0"><span class="c1">Some creatives load assets in a nested x-origin iframe</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Resource Timing</span></p><ul class="c10 lst-kix_92zwylia2gw-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">No control of buffers for SPAs</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Would like to understand the impact of network contention.</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Issue with 3rdParty:</span></li></ul><ul class="c10 lst-kix_92zwylia2gw-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">Ad resource don’t optin to TAO header</span></li><li class="c3 c16 li-bullet-0"><span class="c1">No visibility when ad loads nested CO iframes</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Long Tasks/CPU</span></p><ul class="c10 lst-kix_zigfdtz9pu7t-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Need better attribution</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Some ads are consuming lots of CPU. Would be nice to know which ads</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Self Profiling</span></p><ul class="c10 lst-kix_c0d94mf0u9td-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Needs:</span></li></ul><ul class="c10 lst-kix_c0d94mf0u9td-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">Measure parse and compile time</span></li><li class="c3 c16 li-bullet-0"><span class="c1">Attribution for native tasks</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Resource Hints</span></p><ul class="c10 lst-kix_h3e2fv4cmf9v-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Need explicit priorities from ad publishers</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Thread Scheduling</span></p><ul class="c10 lst-kix_jxj988oac1jn-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">We are very greedy with the thread (as we don’t know when we get it back)</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Going to look into isInputPending</span></li><li class="c3 c6 li-bullet-0"><span class="c1"><b>Would love</b>: isPaintPending</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Beaconing</span></p><ul class="c10 lst-kix_ys3qtqydi841-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Challenges</span></li></ul><ul class="c10 lst-kix_ys3qtqydi841-1 start"><li class="c3 c16 li-bullet-0"><span class="c1">Could be a lot of beacons</span></li><li class="c3 c16 li-bullet-0"><span class="c1">Ok with beacon loss</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Memory Pressure/Leak</span></p><ul class="c10 lst-kix_o3c3kswyzx42-0 start"><li class="c3 c6 li-bullet-0"><span class="c1">Impacts ad metrics</span></li><li class="c3 c6 li-bullet-0"><span class="c1">Memory leak detection</span></li></ul><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c1">Questions:</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: Scheduling talk this afternoon. Will talk about scripts yielding and getting back control. There’s also a proposal for isFramePending.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: are you considering script abortion?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: More about chunking work and yielding at certain point</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: abortion would mean that script would have to opt-in to be abortable, which 3rd party won’t be incentivized to</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: We have a use case for that, but agree that 3rd parties may not</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Risky to have scripts killed at any point with no chance to cleanup state </span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Work Scheduling: there is a token to allow the ability to abort something in the queue</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Before it started</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: yeah</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: with postTask, you can cancel tasks. &nbsp;<b>yield is different</b>: there is no way currently to kill something in the queue. Yield returns a promise. Browser will resolve the promise.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: is it like async/await but with a different api ?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: correct. Yield returns a promise that resolves once the scheduler returns control to the script</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: so that API won’t support being cancellable</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: yeah, as currently proposed it won’t</span></p><a id="id.sagvdwcwhq1h"></a><h2 class="c14" id="h.x0ih8vnl6qwo"><span class="c12">JavaScript memory API - Ulan Degenbaev (Google) </span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1o8KpUJclVBDKfnOczvlUJzWulh6dsn1AJtgRTULxuhY/edit?usp%3Dsharing&amp;sa=D&amp;source=editors&amp;ust=1623069033956000&amp;usg=AOvVaw265fK_51SMT5VpBorAmpcU">Slides</a></span><span class="c13">, </span><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D11703&amp;sa=D&amp;source=editors&amp;ust=1623069033957000&amp;usg=AOvVaw2aLV7EVWSElTNNTg-1vKkR">video</a></span></p><p class="c3"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 468.00px;"><img alt="" src="./WebPerf WG F2F June 2019 Minutes_files/4E4694C6-DBF7-43E0-B033-9D23258E8A33.jpeg" style="width: 624.00px;<b> height</b>: 468.00px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: work on v8</span></p><p class="c3"><span class="c1">… this proposal is trying to take in all the learnings from previous attempts</span></p><p class="c3"><span class="c1">… common thread and challenge is privacy </span></p><p class="c3"><span>… we collected </span><span class="c8 c0"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/document/d/1u21oa3-R1FhHgrPsh8-mpb8dIFVj60wcFiM5FFrfIQA/edit&amp;sa=D&amp;source=editors&amp;ust=1623069033958000&amp;usg=AOvVaw1BYwEjO9lfQayyG20n-Qo8">use cases</a></span></p><p class="c3"><span class="c1">… Why should we measure it?Is memory pressure API sufficient?</span></p><p class="c3"><span class="c1">… They’re different APIs and signals. Memory pressure API does not address the use cases of A/B tests or regressions; Heap size doesn’t tell you when you have memory pressure </span></p><p class="c3"><span class="c1">… trade-offs: developers want complete picture, but full cross-origin attribution potentially exposes user data; implementers want easy and fast implementation.</span></p><p class="c3"><span class="c1">… the complicated part is finding the “right” tradeoff</span></p><p class="c3"><span class="c1">… our design is security-first</span></p><p class="c3"><span class="c1">&nbsp; &nbsp;… origin based security (originally wanted site based, but security folks convinced otherwise)</span></p><p class="c3"><span class="c1">&nbsp; &nbsp;… account only objects that the calling context can access</span></p><p class="c3"><span class="c1">&nbsp; &nbsp;… we don’t want to rely on mitigations like buckets/noise, delaying, etc. Also didn’t want to rely on site-isolation.</span></p><p class="c3"><span class="c1">… given these requirements, we only account for JS exposed objects</span></p><p class="c3"><span class="c1">… the proposal is to provide a promise based API (e.g. performance.measureMemory()).</span></p><p class="c3"><span class="c1">… could provide an escape hatch for some security sensitive – e.g. throw an exception. Would also be possible to extend the same API to more types of memory (not just JS heap) as security allows. Limiting to JS objects allows to strictly define accounting in terms of Realms. For cross origin resources, they are either outside the JS heap, or we can run security checks on platform objects.</span></p><p class="c3"><span class="c1">… API returns a result as well as a range in case precise calculation was too expensive. Can also provide optional per-frame attribution. (optional because it may be difficult to implement in some architectures)</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: for same origin frames, how do we account for objects that move between realms?</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: That could be implementation dependent, as some implementation may use an abstraction Realm in those cases.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: If you construct a function that has properties from multiple Realms, it’s ambigious as to what we need to report.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: The ambiguity here seems fundamental, because objects can move around</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Right.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Any security issues with just using the creation context and reporting on that? </span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: That would work for same origin, less so for foreign origins</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Also, there would be runtime implications, as implementations would have to remember where everything was created</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: May have changed, but I think Gecko does that kind of object decoration. WebKit and Chrome do not</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: I think it’s a corner case</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: I think it’s pretty common. People create objects inside iframes and then move them out.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Links across iframe boundary is a *really* common source of memory leaks.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Different performance characteristics depending on context.</span></p><p class="c3"><span class="c1">… Single JS agent with same-origin realms or web workers can just return heap size.</span></p><p class="c3"><span class="c1">… For different-origin realms on the heap, more detailed accounting is needed. </span></p><p class="c3"><span class="c1">… options for different-origin realms</span></p><p class="c3"><span class="c1">… origin isolation, hopefully, becomes a thing across browsers</span></p><p class="c3"><span class="c1">… If not, browsers can throw security error or rely on memory-allow-origin similar to TAO, or CORP policy</span></p><p class="c3"><span class="c1">… They can also iterate the heap and only report what they can. Could be rate-limited.</span></p><p class="c3"><span class="c1">… They could also account on allocation or do heap segregation</span></p><p class="c3"><span class="c1">… We have an explainer on GitHub and discourse thread, feedback welcome</span></p><p class="c3"><span class="c1">… The meta insight here is that we need to focus on security first</span></p><p class="c3"><span class="c1">… Questions?</span></p><p class="c3"><span class="c0">Tim</span><span><b></b>: You report this as a range.</span><span class="c1">&nbsp;Where do the lower and upper bounds come from?</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Can be the same value if the implementation is certain of the result. If the implementation is less certain, the ranges can help implementations report something useful without crawling every single object.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Crawling cross-origin objects can be used as a timing attack vector.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Implementations can fuzz that time, as it is promise-based</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, but those attacks can be amplified (e.g. by creating a 1000 iframes)</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: yeah, but response time can be infinitely fuzzed</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: There was a slide saying we want to avoid such mitigations </span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: yeah, regarding the return values, not the time it takes to get them</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Fair to say that the time can introduce timing attacks, so maybe worth while to indicate the response has to be at least as slow as some value</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: We could also wait for next natural GC. It’s just a bit risky to trigger new work based on the request.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: folks that would consume this API and mentioned memory, would this solve the problem?</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: mostly were requests around leak detection</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: regressions should be detectable via this proposal, as long as it’s a same-origin leak</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: This will signal that there is a leak</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, you can measure over time from known-good-state and see if it keeps increasing</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Would that expose live memory or GCed memory?</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Live as we don’t want this to force GC. This makes sense for large scale experiments when you can get data from production. For local experiments, you can expose GC via a flag</span></p><p class="c3"><span class="c0">Steven</span><span class="c1"><b></b>: In the lab, this is exactly what we do. Iterate the same thing and trigger GC to see the current live size. This will be able to give us an indication something is leaking, but not beyond that.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Yeah, this can be an indication, but you need another solution to make it actionable.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: memory can spike up until points where GC happens, which can make it tricky to find the exact point of the leak.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: This API is not something that’s intended to be used every 50ms. GC will kick in at some point.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Eventually, but it may be hard to detect small leaks that way</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Can this indicate how much is a site consuming at a particular point over time, over many users? (e.g. “how much memory am I using at page load time”)</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: yeah, in such cases GC timing should average out</span></p><p class="c3"><span class="c0">Vikram</span><span class="c1"><b></b>: our app (teams / msft) is SPA in Electron.. Our app runs for days, so small leaks matter. Electron exposes this today. On the web we are currently blind. Something like this would be really really helpful</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: would be interesting to see if folks find live heap reports useful at scale. If that’s good enough, that’s great.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Naively, can we wait until after the next GC?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: That would leak GC timing</span></p><p class="c3"><span class="c0">Andrew</span><span class="c1"><b></b>: What about the last GC time that’s revealed K seconds into the future? So you can see only the GCed memory, but can’t tell *when* it happened</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: We need to do something like that.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: You might still be able to force GC so that might still leak some data on that.</span></p><p class="c3"><span class="c0">Steven</span><span class="c1"><b></b>: full memory vs live, ideally we would surface live as that would make our attribution much easier and require less data</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: our hope is that at large scale you can average out the differences and A/B detect regressions and leaks</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Concerned that not measuring GC times will make it harder to detect leaks on the same session, as not-yet-GCed memory will make it hard</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Maybe we can measure the number of reachable objects, instead of memory?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: You’d have to run GC for that</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: or you could remember that from the last GC</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: If an attacked can force a GC to happen, that can leak information</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Is the connected node tree a sensitive cross-origin info?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yes. afaik, browsers don’t isolate heaps today so exposing GC times can leak data. You’d be able to infer how much memory was used by another cross-origin frame by triggering GC on your frame. </span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: we can report in regular intervals, no?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, but fuzzing can be amplified away</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: there is existing API that this builds on, correct? And this will be a better version of that.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: This is significantly better, as right now performance.memory only reports global heap size, so you don’t know which frame the numbers are coming from</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Have people successfully detected leaks with that?</span></p><p class="c3"><span class="c0">FB+Google</span><span class="c1"><b></b>: yes, we have examples where existing API helped identify major issues</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Is that just leaks or memory usage growth? </span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: A lot of that is leaks.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: great info!</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Also detected leaks in Chrome itself between different versions</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: there is also the memory pressure API we’ve discussed before. We also talked about full process memory that maybe origin isolation primitives will enable (from a security perspective)</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Specific about memory pressure, 2 years ago there was a lot of interest. is there still interest?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: yes, we’re still interested</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: ditto</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: I think large properties said they are not so interested</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, folks said they are more interested in something like this to detect leaks. Memory pressure can be useful for games, where frame can free up memory to try to stay alive. It can also expose a different signal — e.g. uploading an image that causes pressure</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Can’t they do that when hidden?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: App can still be visible when this happens</span></p><p class="c3"><span class="c0">Nate</span><span class="c1"><b></b>: An API like the one proposed here is more useful than memory pressure. Memory pressure can be useful, but lower priority. Having the numbers from this can make memory pressure more useful</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Reporting API does report OOM</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Correlating memory pressure to JS heap memory can lead you to insights. We could also include page visibility and reporting to tell website devs they are using too much memory.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, right now developers just know that the user disappeared but don’t know why (unless they have reporting implemented)</span></p><p class="c3"><span class="c0">Nate</span><span class="c1"><b></b>: We found multiple regression types with performance.memory and it does change how much time people spend on your site</span></p><p class="c3"><span class="c1">&nbsp;</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Seems like the use cases are larger than the scope of this particular solution. Would be great to have a unified use case + solution doc</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Yeah, a Venn diagram of how this, memory pressure, reporting, etc all come together</span></p><p class="c3"><span class="c1"><b>Benjamin</b>: this would be a Very Palatable™ &nbsp;way to start</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Previous API has massive security issues, this looks very promising.</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: Regarding memory pressure, I wonder if JS weakrefs would resolve some of the use cases, as they allow to create caches that are not cleared on garbage collection</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: We found that it’s not so much objects that need to be freed, but the way people use them (e.g. copying image to multiple canvases without waiting for GC and eventually crashing)</span></p><p class="c3"><span class="c0">Ulan</span><span class="c1"><b></b>: But memory pressure would be an indication they should clear those weakrefs</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: In that example, you don’t want your canvasses to be weakrefs</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Memory pressure can also be related to background user activity. That can happen fast.</span></p><p class="c2"><span class="c1"></span></p><h2 class="c14" id="h.ptau5ck3jdlk"><span>Main Thread Scheduling APIs - Scott Haseley (Google)</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://docs.google.com/presentation/d/1GUB081FTpvFEwEkfePagFEkiqcLKKnIHkhym-I8tTd8/edit?usp%3Dsharing&amp;sa=D&amp;source=editors&amp;ust=1623069033971000&amp;usg=AOvVaw1P_kzO5dx-a9M_MJLH3AIk">Slides</a></span><span class="c13">, </span><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://youtu.be/eyAW4FuSgyE?list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D14387&amp;sa=D&amp;source=editors&amp;ust=1623069033971000&amp;usg=AOvVaw1eLF4tV-OVZYAZgvfJxB0n">video</a></span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: long tasks are the enemies of responsiveness (but you know that)</span></p><p class="c3"><span class="c1">… goal is to break up long tasks</span></p><p class="c3"><span class="c1">… be responsive to input, keep animations smooth, minimize app latency</span></p><p class="c3"><span class="c1">… however, breaking up long tasks helps to a degree</span></p><p class="c3"><span class="c1">….. Helps with responsiveness and visual jank, but doesn’t solve all the problems</span></p><p class="c3"><span class="c1">….. You can have buttery animations but high app latency</span></p><p class="c3"><span class="c1">… apps like maps, or frameworks like react build their own schedulers</span></p><p class="c3"><span class="c1">… user space schedulers have priorities, have a task queue model</span></p><p class="c3"><span class="c1">… a scheduling task will run one or more queued tasks</span></p><p class="c3"><span class="c1">… for the most part such schedulers work well, but there are limitations where we can help</span></p><p class="c3"><span class="c1">… e.g. it’s a challenge to know when to yield: doing it is overhead + regaining control</span></p><p class="c3"><span class="c1">… one of the problems is that there is not a lot of incentives for yielding (when you have competing scripts, etc)</span></p><p class="c3"><span class="c1">… similarly, if you break your long task but there are other tasks, you end up being delayed</span></p><p class="c3"><span class="c1">… the idea with continuation is that it gives you incentive to resume</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: this would be really useful for “selection” use case in excel. Resizing a div based on mouse movements, while being able to handle more input events; inputPending would help as well</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: So the Excel use-case is triggered from an input event, and they want to rest of the flow to inherit the scheduling of that initial input event</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: How often would folks use setTimeout vs. rAF in those cases?</span></p><p class="c3"><span class="c0">Andrew</span><span class="c1"><b></b>: I thought setTimeout in the slide just refers to some task.</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: Yeah, but rAF is an implicit higher priority as it’s a “rendering opportunity”</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: In Chrome</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: “Rendering opportunity” is a spec quote</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: yeah, but we don’t prioritize it. We have no scheduler. Rendering may happen faster as an artifact, but not deliberately.</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: we’re proposing scheduler.yield with optional priority</span></p><p class="c3"><span class="c1">… returns a promise that is resolved when higher priority work is finished</span></p><p class="c3"><span class="c1">… priority argument integrates with scheduler.postTask() </span></p><p class="c3"><span class="c0">Andrew Clark</span><span class="c1"><b></b>: we try to do this in react today, We have our own scheduler and plan to try and do the same for non-React code by replacing setTimeout with our implementation</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: another use case. A dynamic buy button that depends on 3P code that needs to run to identify which provider is best for the user; ideally this would be done in background</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: [excel use case] - long calculation would benefit from that and live on the main thread instead of moving to a worker. Would also benefit from a “is fetch handler pending” API</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: Looking into inheriting priority from network fetches, so you’d be able to check if high priority fetches are pending, or other high priority tasks.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: So “is high priority thing pending”?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: Kinda</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: Maybe LongTasks can also report what triggered them?</span></p><p class="c3"><span class="c0">Tim</span><span><b></b>: Fairly straightforward to add that and seems useful</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Frameworks including this would mean customers get this out of the box. That working in concert with the browser’s scheduler would be extremely powerful</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: priority is another common primitive across all the schedulers</span></p><p class="c3"><span class="c1">… e.g. for maps you may have different priorities for stuff on screen, near the screen, etc.</span></p><p class="c3"><span class="c1">… the problem is that schedulers can’t interact with other priorities</span></p><p class="c3"><span class="c1">… AirBnB: has own scheduler, plus React and Maps, each of which has its own priority system</span></p><p class="c3"><span class="c1">… we need a way to coordinate across schedulers; </span></p><p class="c3"><span class="c1">… the idea is to provide a new set of inter-frame priorities</span></p><p class="c3"><span class="c1">… introduce notion of tasks, tasks are posted to queues and each queue has priority</span></p><p class="c3"><span class="c1">… each window has a scheduler — i.e. window.scheduler</span></p><p class="c3"><span class="c1">… you can move across task queues</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: You example of multiple frameworks with different priority queues, a single queue would work only if they share the same priority semantics, right?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: Yeah. There would also be a difference between userland “high” and browser “high”. Would be good to figure out significant meaningful names</span></p><p class="c3"><span class="c0">Plh</span><span class="c1"><b></b>: So you could change the priorities or cancel tasks?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: yeah, you could move tasks between queues. Also, we want to create user-defined task queues, so that developers will be able to lower the priority of the entire queue (e.g. if a series of tasks is no longer important because the user did something)</span></p><p class="c3"><span class="c0">Andrew Clark</span><span class="c1"><b></b>: the names are important, “high” vs “low” is an arms race and in the face of starvation, devs are doing the wrong thing. We prefer basing names on user experience signals, or use “shaming” names for things we want to discourage</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: is there a way to tell which queue / priority?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: yep, scheduler.currentTaskQueue.priority</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: priority inversion?</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: It’s different from the classic priority inversion problems. It’s still an open problem, propagating priority to subtasks might help.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Introducing that without priority inversion makes no sense. User action changes priorities of things, and it can create head-of-line blocking issues.</span></p><p class="c3"><span class="c0">Andrew Clark</span><span class="c1"><b></b>: That’s already the status quo, as there’s no shared notion. </span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: this is a blocker. You need to solve this problem</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Is the problem that the current task is blocking, or the new task that we haven’t yet started?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: A new high priority task can rely on a current low priority one</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: But tasks are not interruputable unless they are yielding</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: So you want reprioritization of submitted tasks that haven’t started yet </span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: right</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: That’s already in the proposal</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Ryosuke, are you asking for declaring dependency</span></p><p class="c3"><span class="c1">… we did this in .net </span></p><p class="c3"><span class="c1">… the first primitive is you need a relationship. Then you need an algorithm that bump up priorities for everything together.</span></p><p class="c3"><span class="c0">Scott</span><span class="c1"><b></b>: We’d consider related things to be in the same queue</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: things may not be initially related. Background tasks may become relevant due to user action.</span></p><p class="c3"><span class="c0">Andrew Clark</span><span class="c1"><b></b>: Hiding a subtree may be a good example. We’re hiding it in low priority and then if it becomes visible, all related tasks become high priority. We can dig further into this use-case, and it might be possible to do that with queues. But need to think this through.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Can’t we build that on top of task queues?</span></p><p class="c3"><span class="c0">Andrew Clark/Scott</span><span class="c1"><b></b>: Maybe. Need to flesh out the use case here</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: Can we list the scenarios we’re not sure are handled and try to push this proposal to those boundaries?</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Edge cases are very welcome</span></p><p class="c3"><span class="c1">&lt;discussing asset management server example&gt;</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: May need some things to live in userland at first</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Important to communicate the dependencies. In iOS we have multiple daemons running tasks, handling dependencies automatically</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: And you’re saying that if userland can’t communicate the dependencies that will not be automatic?</span></p><p class="c3"><span class="c0">Andrew Clark</span><span class="c1"><b></b>: React users will use a React API that will call into this. So would be good to start with core use cases, rather than try to solve all edge cases upfront</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Another use-case is scrolling. Fetch blocks for current viewport, and lazyload the rest, but if the user starts scrolling, we need to bump up the fetch’s priority.</span></p><h2 class="c14" id="h.oluroz2qrd9a"><span class="c12">CPU reporting - discussion</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://www.youtube.com/watch?v%3DeyAW4FuSgyE%26feature%3Dyoutu.be%26list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D17778&amp;sa=D&amp;source=editors&amp;ust=1623069033983000&amp;usg=AOvVaw1-eLfIE8qEK90IUZEX_M91">Video</a></span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">Steven Bougon</span><span class="c1"><b></b>: Users complain about salesforce being slow. Currently, they need to ask the customer to run Octane as a baseline of “Is the machine/browser ok?”. Could this be integrated or could an API be provided?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Can reveal background activity, which can be a privacy concern.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Can be short-lived to avoid fingerprinting concerns.</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: Wikimedia is trying to figure out whether their website is getting faster/slower normalized against hardware. Without some type of API exposing the speed of the hardware, it is very difficult to reason about this. Today, Wikimedia does this by using Network Information to segment the data.</span></p><p class="c3"><span class="c0">Utkarsh</span><span class="c1"><b></b>: Customer asked for CPU of device to block 3rd parties. If low score from Geekbench, consider blocking 3rd party content to improve performance. UA string model number and www.gsmarena.com model enabled this to be done for some devices. This is only an approximation as battery throttling and core choice have an impact. We need to know the CPU on which the page was loaded, as opposed to what all CPUs are available on the device. </span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: 3rd party content blocking in order to improve 1st party performance?</span></p><p class="c3"><span class="c0">Utkarsh</span><span class="c1"><b></b>: Correct</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: Benchmarks can vary on the same device by 2X on a device with the same UA string.</span></p><p class="c3"><span class="c0">Steven</span><span class="c1"><b></b>: Today, Salesforce uses Network Information to reason about Network. A benchmark can be run on a web worker to benchmark speed. Can the same use case be solved by directly exposing information?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: ECT is derived from bandwidth and RTT. What are the equivalents for processing?</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: CPU temperature is highly correlated to actual perf. Load is another signal. Clock speed vs. max clock speed can also be a good signal. </span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: The browser can also keep track of parse times and report that.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: It should be based on an operation that’s more consistent </span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: And GPUs or new CPU types will make this more complex…</span></p><p class="c3"><span class="c1">… Use cases I’ve heard are around categorizing runtime perf. Another related to device score for debugging purposes.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Maybe an “I’m currently unhappy” browser API can indicate that something else is happening on the machine, interfering with the browser’s resources compared to a “typical” run</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Excel is interested in learning when not to do something. If Excel can know how fast the machine is, they can choose not to pre-emptively run background calculations.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: The thing Excel cares about is how fast the Excel operation can be completed based upon the time needed to complete the operation.</span></p><p class="c3"><span class="c0">Gilles</span><span class="c1"><b></b>: But we also want to know how devices are related to each other.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: So buckets of “device types” and in them, “under pressure” indicators.</span></p><p class="c3"><span class="c0">Utkarsh</span><span class="c1"><b></b>: We must ensure that privacy/security is respected if anything is exposed. Also, recording CPU-related info in RUM reports can help associate web performance metrics with the CPU profiles on the device, rather than the device names/models. That association can also help build buckets to classify a device as slow/fast/etc.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: It sounds like there are multiple use cases. Are any volunteers available to write them up?</span></p><p class="c3"><span class="c0">Utkarsh</span><span class="c1"><b></b>: I’m interested in writing this up. I’d like help.</span></p><p class="c3"><span class="c0">Steven/Noam/Beng/Gilles/Benjamin</span><span class="c1">&nbsp;are all interested in assisting.</span></p><h2 class="c14" id="h.mdnqofs1n3yc"><span>Metrics for Single Page Apps</span><span class="c12">&nbsp;- discussion</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://www.youtube.com/watch?v%3DeyAW4FuSgyE%26feature%3Dyoutu.be%26list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D19183&amp;sa=D&amp;source=editors&amp;ust=1623069033988000&amp;usg=AOvVaw1FqzqhyW01TmRzwDe6pM9e">Video</a></span></p><p class="c3"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 329.33px;"><img alt="" src="./WebPerf WG F2F June 2019 Minutes_files/pasted image 0.png" style="width: 624.00px;<b> height</b>: 329.33px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></p><p class="c3"><span style="overflow: hidden;<b> display</b>: inline-block;<b> margin</b>: 0.00px 0.00px;<b> border</b>: 0.00px solid #000000;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);<b> width</b>: 624.00px;<b> height</b>: 325.33px;"><img alt="" src="./WebPerf WG F2F June 2019 Minutes_files/pasted image 0(1).png" style="width: 624.00px;<b> height</b>: 325.33px; margin-left: 0.00px; margin-top: 0.00px;<b> transform</b>: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);" title=""></span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Many of our metrics are focused around page load. We hear that there’s a gap. Analytics are doing crazy heuristics, instrumenting frameworks in order to get a better view of soft navs. </span></p><p class="c3"><span class="c1">We should be able to abstract some heuristics. Some of our metrics were designed to fire only once and we use that as a security boundary. We could reset when soft navs are detected, but it might not work for everything. We have many “first…” metrics, but don’t account for the rest of the lifecycle. Maybe there’s a way to define soft navs and all the current metrics would just work.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Don’t have to reset, but maybe we can have more than one navTiming entry</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: in SPA mode we don’t report onload event as “primary time”. We start our own monitoring using mutation observer, look into “important” things that are loaded into the DOM, and once they have quieted down and added to RT, we consider the page done. Similar heuristics for in-page navigations - “soft nav”. We listen to many framework specific events (Angular/React events, history state). Also look back to the last input event to see when activity started from the user’s perspective. Don’t measure things like FirstPaint, etc in that mode, as the browser doesn’t provide those facilities.</span></p><p class="c3"><span class="c1">... Lots of negative side effects of monitoring all of these. Sub-resources/CSS cannot be monitored. Want better understanding of in-flight requests. Standardizing something in this space could allow dev tools and different RUM providers to expose the same things.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: 2 approaches: 1. Heuristics triggered by browser 2. App triggers a state change</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Do we know what is a single page app nav? Seems like there is a lot of room between a small response to input and a full single page app nav. Should we consider exposing reactions to input to expose all interactions?</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Adding to that, Ilya mentioned it’s an antipattern to instrument frameworks. I think it can be useful for sites with similar stack to be able to compare themselves to one another.</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: Akamai allows the customer to control what is recorded. They can enable heuristics or they can trigger a start in their app.</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: Sounds like we should do everything and the downside is: we have to do everything. A big customer that signals the beginning and end of softnavs had a lot of pageviews that had page load time of 0. They instrumented a custom modal dialog as a soft nav and found they had exceptionally good time. But they wanted to measure that. </span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Can also happen with prefetching.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: A complex DOM might trigger layout which could increase 0 to longer even without network</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: There are always customers who want to monitor everything or only to monitor a bit. Can we enable both? We need to give them a way to signal soft-navs</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Does push state indicate a soft nav is happening?</span></p><p class="c3"><span class="c0">Many</span><span class="c1"><b></b>: Push state isn’t sufficient</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Modern frameworks may not implement a push state update correlated with user update</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Sometimes push state is too much. He has a charting app that updates push state regularly but he wouldn’t want timing.</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: They have ~60-70% of users that opt in to push state. For many of the remaining users, push state won’t be sufficient.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Having an explicit signal will enable us to evaluate heuristics against it</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: If push state is the signal and it covers 60-70% of the web, is that a good start?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: What happens with the others?</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: Could we start by asking developers to implement a start/end to declare soft nav?</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: On top of Event Timing, considering the addition of a promise that is completed when the event handling chain completes. Resolve when website author considers the nav done.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Can this be tied to User Timing? For the chart app, the signal may cross input to fetch to paint. Maybe some state changes aren’t like navigations. They are state changes and have different characteristics from a load. It may not be possible to abstract this completely.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Explicit signals can help us to kick off “navigation timing” entries as well as paint metrics after that.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: But maybe in some apps it’s different from a page load. Maybe the devs need to measure a subset of the current metrics for soft-navs. (e.g. the chart app and load event)</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Load events may not make sense but paint timing would</span></p><p class="c3"><span class="c1"><b>Ryosuke</b>: maybe, but maybe not. In SPAs the metric may vary based on your app.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Devs want something out of the box that works for most, but maybe more control for the rest of cases. Maybe we can’t get it perfect.. Can we get something good enough for the 80% case?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Should the things being tracked be a combination of Event Timing and Element Timing and Paint Timing? Maybe we need to answer “when is this element painted next time?”.</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: This feels like it would be the new normal</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: I imagine ElementTiming for this usecase. But you want to set the right time base (e.g. the input event, not the page navigation). So maybe we need to be able to set the timebase in ET.</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: When a soft nav is triggered, a lot of RUM information is reset to track the new soft nav information. Fundamentally different than the navigation-based view. Sometimes resource timing analysis tied to soft navs requires this to understand heavy resource use/queueing.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Maybe this is more related to resource timing dependency graphs than to soft navs?</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: We wanted to start by instrumenting React. User interaction-&gt;DOM Change-&gt;done?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Does react have a link between input and consequent changes?</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Not really.</span></p><p class="c3"><span class="c0">Houssein</span><span class="c1"><b></b>: React is looking at wrapping component renders in User Timing</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Shadow root and resource loads from within the shadow root could allow understanding. Each component could have its own performance timeline.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: But resource loads are global</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Yeah, but you could report it to the component</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: You could, but that’s not currently the case. Theoretically, we could move to that model for RT as well, and the WC is itself its own navigation.</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Component can be very small or a very large part of the page </span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: For long tasks, that’s complicated as they are not tied to a component.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Neither are resources</span></p><p class="c3"><span class="c0">Tim/Nicole/Ryosuke</span><span class="c1"><b></b>: Both global view and local view are useful to understand performance</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Are those separate issues that must both be solved? Lifecycle of WC and lifecycle of the page both need to be measured</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: A flag in the global timeline would be problematic in cases where we have 2 independent “component navigations” happening at the same time.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: What would be the URL in that case?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: That would be a good case for component based measurements. </span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Excel workbook has multiple tabs. The URL stays the same but a soft nav occurs when the tab is changed. We potentially issue requests, change the DOM and expect to measure when all that work is finished.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: If another is clicked before the previous is done?</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: It will be considered cancelled. Also, this “component navigation” triggers changes in other page components.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: So is that a component navigation, page navigation or both?</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Component navigation </span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Played with ideas that if devs provided us about a dependency graph, we can better know what to load</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: For us it’s not a static tree, it’s totally dynamic</span></p><p class="c3"><span class="c0">Steve</span><span class="c1"><b></b>: Components seems like a separate issue compared to SPA soft navs.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Seems like there’s a lot of value in exposing “start” and “end” signals for developers, even beyond SPAs. Onload is not relevant, but there’s no way for devs to tell the browser what is.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: We have that in User Timing and nobody ever used</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: People didn’t use them because they were hard</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Libraries are not consistent in when they kick off pushState.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: So something like that could work?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: SPA can vary and end time is app specific.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Would that navigation initiation be associated with an event?</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: Not necessarily. Could be timer based.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Youtube kicking off another video after you finished the first is another case.</span></p><p class="c3"><span class="c1"><b>Tim</b>: In cases where input is the trigger, we can use the HW timestamp</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: We shouldn’t try to find the heuristics here. Need to define an API first.</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Can devs mark the “navigation ended” bit now? Do they have that info?</span></p><p class="c3"><span class="c0">Nicolás</span><span class="c1"><b></b>: Once the developer marked navigation end and another started, we need to reset the performance timeline.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Dunno is we want to reset, or just distinguish them from the new ones</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: User Timing names didn’t work because it didn’t do anything. If they impacted NavTiming and Paint Timings that would motivate developers to use the new signal</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Framework authors are motivated to show download impact. Currently only measuring the first load and not SPA navs which are supposed to be faster.</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: Would be great if frameworks adopted heuristics, and users will get them automatically.</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: Could indicate “next paint after this”.</span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: Yeah, need that also on a DOM basis</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Element Timing can give you that.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Can we just create a new Performance Timeline?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: So an array of Performance Timeline?</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Yeah, with a new time origin</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: A little worried about N performance timelines. &nbsp;</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: That would enable us to get first contentful paint again.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: so yes we need a new Performance Timeline. But there are security issues.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: so what are the core requirements?</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: it seems we need an API to mark start and end.</span></p><p class="c3"><span class="c0">Nicolás</span><span class="c1"><b></b>: why do we need an end mark?</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: to replace onload. We tell people to ignore onload, and have nothing better to give them. But maybe they don’t need to be coupled.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: over time we can provide better tools to get to the right end state.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: maybe in UserTiming have a flag to mark the ‘start’.</span></p><p class="c3"><span class="c0">Steve Souders</span><span class="c1"><b></b>: don’t think we want N timelines, but know start and end times and when someone is at the end of the SPA soft nav and they ask for the total longtasks the API could take start and end into account and only give the relevant entries. </span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: getEntriesByNav</span></p><p class="c3"><span class="c0">Nic</span><span class="c1"><b></b>: and that’s essentially what we’re doing today.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: it needs to be easy to make the start time be the input event.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: possible with UserTiming.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: does not get new FCP but maybe ok for first attempt?</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: isn’t that the whole point? We need incentive for developers to do this.</span></p><p class="c3"><span class="c0">Ryosuke</span><span class="c1"><b></b>: painting cannot account for cross origin stuff.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: any volunteers for documenting the use cases?</span></p><p class="c3"><span class="c0">Tim / Nic / Noam</span><span>&nbsp;volunteer</span><span class="c1">.</span></p><h2 class="c14" id="h.ss0pq2xgjdg4"><span class="c12">Group processes</span></h2><p class="c3"><span class="c8 c13"><a class="c7" href="https://www.google.com/url?q=https://www.youtube.com/watch?v%3DeyAW4FuSgyE%26feature%3Dyoutu.be%26list%3DPL5b8e1JT2i4a3PqaF4a6tVfqZela-pSky%26t%3D22522&amp;sa=D&amp;source=editors&amp;ust=1623069034001000&amp;usg=AOvVaw0rTM5L959Cp3tzykf0mfKy">Video</a></span></p><p class="c2"><span class="c17 c13"></span></p><p class="c3"><span class="c0">Steven</span><span class="c1"><b></b>: We may want to pre-allocate scribes. Multiple scribes can be useful to catch up for one another. Also for the meetings, would be good to change scribes halfway. Also, we can create a pool of scribes and randomize between them.</span></p><p class="c3"><span class="c1">Otherwise, we could have Slack as a complement to the meeting to see that run quick polls. </span></p><p class="c3"><span class="c1">Hangout chat is not great as it disappears after the call.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Is there W3C slack?</span></p><p class="c3"><span class="c0">plh</span><span class="c1"><b></b>: Yes and no. Some working groups are creating their own slacks</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Stuff in slack isn’t linkable.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Let’s put this as something we can improve.</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">AI - Todd/Yoav</span><span>&nbsp;look into an IM solution to augment the calls</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: We could also delegate the meeting scribe to someone later after the fact.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: We could keep recording and scribe’s job could be just recording action items, etc…</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: That would help making scribe’s job considerably easier</span></p><p class="c3"><span class="c0">plh</span><span class="c1"><b></b>: Automated scribing can end up with a lot of garbage and end up spending a lot of time cleaning up</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Has been getting many contacts to get involved. Maybe some people in the community are interested in getting involved</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: I’m happy to get Skype team involved who are working on automated transcription</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: It’s really hard to capture all the nuances of technical discussions happening at the speed of conversation</span></p><p class="c3"><span class="c0">Nicole</span><span class="c1"><b></b>: I find past transcriptions to be very useful</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: I often complete the minutes from the video</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: Agree that minutes are good</span></p><p class="c3"><span class="c0">Steven</span><span class="c1"><b></b>: We could also use a paid scribe that knows the terminology</span></p><p class="c2"><span class="c1"></span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Other feedback we got are creating onboarding guidelines and templates for use cases.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Who wants to get more involved and don’t know how?</span></p><p class="c3"><span class="c0">Beng, Warren, Thomas, Sam</span><span class="c1">&nbsp;raise hands</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: I have an onboarding guide in my team, and it has been very useful.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: What’s the ratio of time we spend discussing new ideas versus working on old bugs?</span></p><p class="c3"><span class="c0">Thomas</span><span class="c1"><b></b>: Old bugs tend to get into browser implementation which are highly irrelevant to my day-to-day work. It would be nice to separate things that are more relevant for developers and ones that are more for web developers.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Any issue could be relevant to web developers. For example, some issues might make it impossible to use beacon or resource timing can’t be used until some issue is resolved. It’s just that a lot of discussions involve three years of work.</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Maybe we could create more focused topic-based groups. We can still have a working group wide meetings but have separate topic based meetings. </span></p><p class="c3"><span class="c0">Noam</span><span class="c1"><b></b>: What’s the current process like?</span></p><p class="c3"><span class="c0">Ilya</span><span><b></b>: The current process is to have </span><span>biweekly meetings.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Overall, both design and triage are useful to people contributing the them. Overall, I felt the balance is reasonable between new features and issue triages.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: That was my impression as well. I wanted to solicit others’ opinions about spending 20+ minutes discussing old issues.</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: Agenda should be available ahead of time, so folks can know if they should join or not.</span></p><p class="c3"><span class="c0">Tim</span><span class="c1"><b></b>: Maybe we can put more exciting stuff at the beginning and let people leave as we get into more boring issues.</span></p><p class="c3"><span class="c0">Todd</span><span class="c1"><b></b>: There is a lot of potential for status dashboard. The working group has a list of standards we’re trying to publish, and each standard needs a set of tests. At a high level, we have a large checklists that we have to complete as the working group. Would be great to make all of that linkable.</span></p><p class="c3"><span class="c0">Benjamin</span><span class="c1"><b></b>: Operationaly, I think this working group is functional and in a pretty high state.</span></p><p class="c3"><span class="c0">Plh</span><span class="c1"><b></b>: Great to hear that from Mozilla</span></p><p class="c3"><span class="c0">Ilya</span><span class="c1"><b></b>: Thanks all!</span></p><p class="c3"><span class="c0">Yoav</span><span class="c1"><b></b>: And see you at TPAC!!</span></p><p class="c2"><span class="c1"></span></p></div></div><div id="footer"><span>Published by <a target="_blank" title="Learn more about Google Drive" href="https://docs.google.com/">Google Drive</a></span><span class="dash">–</span><a href="https://docs.google.com/u/0/abuse?id=AKkXjoxmY6xoYUMzLfxU4MGUvm6lV82HsxZ7JC2kvQwHTeU6yG-k9kBwj6KBM0-3-TEaI9JhdBslJe-kUrt-fZ0:0">Report Abuse</a></div><script type="text/javascript" nonce="">(function(){/*

 Copyright The Closure Library Authors.
 SPDX-License-Identifier: Apache-2.0
*/
var aa="function"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};
function ca(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");}var da=ca(this);function ea(a,b){if(b)a:{var c=da;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}}var h;
if("function"==typeof Object.setPrototypeOf)h=Object.setPrototypeOf;else{var l;a:{var fa={a:!0},ha={};try{ha.__proto__=fa;l=ha.a;break a}catch(a){}l=!1}h=l?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var ia=h;
function m(a,b){a.prototype=aa(b.prototype);a.prototype.constructor=a;if(ia)ia(a,b);else for(var c in b)if("prototype"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.m=b.prototype}ea("Object.is",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});var q=this||self;function r(){}function t(a){var b=typeof a;return"object"==b&&null!=a||"function"==b}
function ja(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var d=c.slice();d.push.apply(d,arguments);return a.apply(this,d)}}function ka(a,b){function c(){}c.prototype=b.prototype;a.m=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.A=function(d,e,f){for(var g=Array(arguments.length-2),k=2;k<arguments.length;k++)g[k-2]=arguments[k];return b.prototype[e].apply(d,g)}}function u(a){return a};function w(a){w[" "](a);return a}w[" "]=r;function la(a,b,c){return Object.prototype.hasOwnProperty.call(a,b)?a[b]:a[b]=c(b)};function ma(a){return la(a.prototype,"$$generatedClassName",function(){return"Class$obf_"+{valueOf:function(){return++na}}})}var na=1E3;function x(){}x.prototype.s=function(){return this.j||(Object.defineProperties(this,{j:{value:oa=oa+1|0,enumerable:!1}}),this.j)};x.prototype.toString=function(){var a=y(z(pa(this.constructor)))+"@";var b=(this.s()>>>0).toString(16);return a+y(b)};function A(){}m(A,x);A.prototype.i=function(a){this.h=a;if(a instanceof Object)try{a.v=this}catch(b){}};function qa(a){a.h instanceof Error&&(Error.captureStackTrace?Error.captureStackTrace(a.h):a.h.stack=Error().stack)}A.prototype.toString=function(){var a=z(pa(this.constructor)),b=this.l;return null==b?a:y(a)+": "+y(b)};function B(){}m(B,A);function D(){}m(D,B);function E(){}m(E,D);E.prototype.i=function(a){D.prototype.i.call(this,Object.is(this.g,"__noinit__")?a:this.g)};function ra(){}m(ra,E);var oa=0;function sa(a,b){return"string"==typeof a?a.charCodeAt(b):a.g(b)};function y(a){return null==a?"null":a.toString()}function ta(a){return 65536<=a?y(String.fromCharCode((55296+((a-65536|0)>>10&1023)|0)&65535))+y(String.fromCharCode((56320+((a-65536|0)&1023)|0)&65535)):String.fromCharCode(a&65535)}function ua(a,b){var c=b,d=a.length,e;b=sa(a,(e=c,c=c+1|0,e));var f;if(e=55296<=b&&56319>=b&&c<d)a=f=sa(a,c),e=56320<=a&&57343>=a;var g;e?g=65536+((b&1023)<<10)+(f&1023)|0:g=b;return g};function F(a,b){this.g=a;this.h=b}m(F,x);function z(a){if(0!=a.h){var b="L"+y(ma(a.g))+";";a=a.h;for(var c="",d=0;d<a;d=d+1|0)c=y(c)+"[";return y(c)+y(b)}return ma(a.g)}F.prototype.toString=function(){return"class "+y(z(this))};function pa(a){return la(a.prototype,"$$class/0",function(){return new F(a,0)})};function G(a,b){return null==a?a:b?decodeURI(a):decodeURIComponent(a)};var va=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#([\S\s]*))?$/;function wa(a){a=va.exec(a);for(var b=[],c=0;7>=c;c=c+1|0)a.length<=c||null==a[c]?b.push(null):b.push(a[c]);return b}
function xa(a,b){var c=a.indexOf(ta(35));c=0>c?a.length:c;a:{var d=0;for(var e=b.length;0<(d=a.indexOf(b,d))&&d<c;){var f=ua(a,d-1|0);if(38==f||63==f){if((d+e|0)>=a.length)break a;f=ua(a,d+e|0);if(61==f||38==f||35==f)break a}d=d+(e+1)|0}d=-1}if(0>d)return null;e=a.indexOf(ta(38),d);if(0>e||e>c)e=c;d=d+(b.length+1)|0;b=Math.min(a.length,d);a=a.substr(b,Math.min(a.length,Math.max(d,e))-b|0);c=" ";for(b=0;0<=(b=c.indexOf("\\",b));)36==c.charCodeAt(b+1|0)?(d=y(c.substr(0,b|0))+"$",e=b=b+1|0,c=d+y(c.substr(e))):
(d=y(c.substr(0,b|0)),e=b=b+1|0,c=d+y(c.substr(e)));a=a.replace(/\+/g,c);return G(a,!1)};function ya(a){a&&"function"==typeof a.u&&a.u()};function H(){this.h=this.h;this.g=this.g}H.prototype.h=!1;H.prototype.u=function(){this.h||(this.h=!0,this.j())};H.prototype.j=function(){if(this.g)for(;this.g.length;)this.g.shift()()};var za=Array.prototype.indexOf?function(a,b){return Array.prototype.indexOf.call(a,b,void 0)}:function(a,b){if("string"===typeof a)return"string"!==typeof b||1!=b.length?-1:a.indexOf(b,0);for(var c=0;c<a.length;c++)if(c in a&&a[c]===b)return c;return-1};var Aa=/&/g,Ba=/</g,Ca=/>/g,Da=/"/g,Ea=/'/g,Fa=/\x00/g,Ga=/[\x00&<>"']/;var I;a:{var Ha=q.navigator;if(Ha){var Ia=Ha.userAgent;if(Ia){I=Ia;break a}}I=""}function J(a){return-1!=I.indexOf(a)};function Ja(a,b,c){for(var d in a)b.call(c,a[d],d,a)};var K;function L(a,b){this.i=a===Ka&&b||"";this.j=La}L.prototype.h=!0;L.prototype.g=function(){return this.i};var La={},Ka={};function M(a,b){this.i=b===N?a:""}M.prototype.h=!0;M.prototype.g=function(){return this.i.toString()};M.prototype.toString=function(){return this.i.toString()};function O(a){return a instanceof M&&a.constructor===M?a.i:"type_error:SafeUrl"}
var Ma=/^(?:audio\/(?:3gpp2|3gpp|aac|L16|midi|mp3|mp4|mpeg|oga|ogg|opus|x-m4a|x-matroska|x-wav|wav|webm)|font\/\w+|image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp|x-icon)|video\/(?:mpeg|mp4|ogg|webm|quicktime|x-matroska))(?:;\w+=(?:\w+|"[\w;,= ]+"))*$/i,Na=/^data:(.*);base64,[a-z0-9+\/]+=*$/i,Oa=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i;function Pa(a){if(a instanceof M)return a;a="object"==typeof a&&a.h?a.g():String(a);Oa.test(a)||(a="about:invalid#zClosurez");return new M(a,N)}
var N={},Qa=new M("about:invalid#zClosurez",N);function P(a,b,c){this.i=c===Ra?a:""}P.prototype.h=!0;P.prototype.g=function(){return this.i.toString()};P.prototype.toString=function(){return this.i.toString()};var Ra={};function Sa(a,b,c,d){a=a instanceof M?a:Pa(a);b=b||q;c=c instanceof L?c instanceof L&&c.constructor===L&&c.j===La?c.i:"type_error:Const":c||"";return void 0!==d?b.open(O(a),c,d,void 0):b.open(O(a),c)};var Ta=J("Trident")||J("MSIE"),Ua=J("Edge")||Ta,Va=J("Gecko")&&!(-1!=I.toLowerCase().indexOf("webkit")&&!J("Edge"))&&!(J("Trident")||J("MSIE"))&&!J("Edge"),Wa=J("Macintosh");var Xa=function(){if(!q.addEventListener||!Object.defineProperty)return!1;var a=!1,b=Object.defineProperty({},"passive",{get:function(){a=!0}});try{q.addEventListener("test",r,b),q.removeEventListener("test",r,b)}catch(c){}return a}();function Q(a,b){this.type=a;this.target=b;this.i=!1}Q.prototype.g=function(){this.i=!0};function R(a){Q.call(this,a?a.type:"");this.relatedTarget=this.target=null;this.button=this.screenY=this.screenX=this.clientY=this.clientX=0;this.key="";this.metaKey=this.shiftKey=this.altKey=this.ctrlKey=!1;this.state=null;this.pointerId=0;this.pointerType="";this.h=null;if(a){var b=this.type=a.type,c=a.changedTouches&&a.changedTouches.length?a.changedTouches[0]:null;this.target=a.target||a.srcElement;var d=a.relatedTarget;if(d){if(Va){a:{try{w(d.nodeName);var e=!0;break a}catch(f){}e=!1}e||(d=null)}}else"mouseover"==
b?d=a.fromElement:"mouseout"==b&&(d=a.toElement);this.relatedTarget=d;c?(this.clientX=void 0!==c.clientX?c.clientX:c.pageX,this.clientY=void 0!==c.clientY?c.clientY:c.pageY,this.screenX=c.screenX||0,this.screenY=c.screenY||0):(this.clientX=void 0!==a.clientX?a.clientX:a.pageX,this.clientY=void 0!==a.clientY?a.clientY:a.pageY,this.screenX=a.screenX||0,this.screenY=a.screenY||0);this.button=a.button;this.key=a.key||"";this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=
a.metaKey;this.pointerId=a.pointerId||0;this.pointerType="string"===typeof a.pointerType?a.pointerType:Ya[a.pointerType]||"";this.state=a.state;this.h=a;a.defaultPrevented&&R.m.g.call(this)}}ka(R,Q);var Ya={2:"touch",3:"pen",4:"mouse"};R.prototype.g=function(){R.m.g.call(this);var a=this.h;a.preventDefault?a.preventDefault():a.returnValue=!1};var S="closure_listenable_"+(1E6*Math.random()|0);var Za=0;function $a(a,b,c,d,e){this.listener=a;this.g=null;this.src=b;this.type=c;this.capture=!!d;this.i=e;this.key=++Za;this.h=this.o=!1}function ab(a){a.h=!0;a.listener=null;a.g=null;a.src=null;a.i=null};function T(a){this.src=a;this.g={};this.h=0}T.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.g[f];a||(a=this.g[f]=[],this.h++);var g;a:{for(g=0;g<a.length;++g){var k=a[g];if(!k.h&&k.listener==b&&k.capture==!!d&&k.i==e)break a}g=-1}-1<g?(b=a[g],c||(b.o=!1)):(b=new $a(b,this.src,f,!!d,e),b.o=c,a.push(b));return b};var U="closure_lm_"+(1E6*Math.random()|0),V={},bb=0;function cb(a,b,c,d,e){if(d&&d.once)return db(a,b,c,d,e);if(Array.isArray(b)){for(var f=0;f<b.length;f++)cb(a,b[f],c,d,e);return null}c=eb(c);return a&&a[S]?a.g(b,c,t(d)?!!d.capture:!!d,e):fb(a,b,c,!1,d,e)}
function fb(a,b,c,d,e,f){if(!b)throw Error("Invalid event type");var g=t(e)?!!e.capture:!!e,k=gb(a);k||(a[U]=k=new T(a));c=k.add(b,c,d,g,f);if(c.g)return c;d=hb();c.g=d;d.src=a;d.listener=c;if(a.addEventListener)Xa||(e=g),void 0===e&&(e=!1),a.addEventListener(b.toString(),d,e);else if(a.attachEvent)a.attachEvent(ib(b.toString()),d);else if(a.addListener&&a.removeListener)a.addListener(d);else throw Error("addEventListener and attachEvent are unavailable.");bb++;return c}
function hb(){function a(c){return b.call(a.src,a.listener,c)}var b=jb;return a}function db(a,b,c,d,e){if(Array.isArray(b)){for(var f=0;f<b.length;f++)db(a,b[f],c,d,e);return null}c=eb(c);return a&&a[S]?a.h(b,c,t(d)?!!d.capture:!!d,e):fb(a,b,c,!0,d,e)}
function kb(a){if("number"!==typeof a&&a&&!a.h){var b=a.src;if(b&&b[S])b.i(a);else{var c=a.type,d=a.g;b.removeEventListener?b.removeEventListener(c,d,a.capture):b.detachEvent?b.detachEvent(ib(c),d):b.addListener&&b.removeListener&&b.removeListener(d);bb--;if(c=gb(b)){d=a.type;if(d in c.g){var e=c.g[d],f=za(e,a),g;(g=0<=f)&&Array.prototype.splice.call(e,f,1);g&&(ab(a),0==c.g[d].length&&(delete c.g[d],c.h--))}0==c.h&&(c.src=null,b[U]=null)}else ab(a)}}}
function ib(a){return a in V?V[a]:V[a]="on"+a}function jb(a,b){if(a.h)a=!0;else{b=new R(b,this);var c=a.listener,d=a.i||a.src;a.o&&kb(a);a=c.call(d,b)}return a}function gb(a){a=a[U];return a instanceof T?a:null}var lb="__closure_events_fn_"+(1E9*Math.random()>>>0);function eb(a){if("function"===typeof a)return a;a[lb]||(a[lb]=function(b){return a.handleEvent(b)});return a[lb]};function W(a){H.call(this);this.l=a;this.i={}}ka(W,H);var mb=[];function nb(a){Ja(a.i,function(b,c){this.i.hasOwnProperty(c)&&kb(b)},a);a.i={}}W.prototype.j=function(){W.m.j.call(this);nb(this)};W.prototype.handleEvent=function(){throw Error("EventHandler.handleEvent not implemented");};function ob(a){H.call(this);this.i=a||document.body;this.l=new W(this);a=ja(ya,this.l);this.h?a():(this.g||(this.g=[]),this.g.push(a));a=this.l;var b=this.i,c=this.s,d="click";Array.isArray(d)||(d&&(mb[0]=d.toString()),d=mb);for(var e=0;e<d.length;e++){var f=cb(b,d[e],c||a.handleEvent,!1,a.l||a);if(!f)break;a.i[f.key]=f}}m(ob,H);
ob.prototype.s=function(a){if(!(0!=a.h.button||Wa&&a.ctrlKey||a.i))for(var b=a.target;b&&b!=this.i;){if(b.tagName&&"a"==b.tagName.toLowerCase()){var c=b.getAttribute("href")||b.getAttributeNS("http://www.w3.org/1999/xlink","href"),d=c;try{var e=wa(c),f;if(f="www.google.com"===G(e[3],!0)){var g=wa(c);f="/url"===G(g[5],!0)}if(f){var k=xa(c,"q");d=k?k:xa(c,"url")}}catch(v){a:{var p=v;if(null!=p){var n=p.v;if(null!=n){v=n;break a}}if(p instanceof TypeError){var C=n=new ra;C.l=y(p);qa(C);n.g="__noinit__";
n.g=p;n.i(new TypeError(n));p=n}else C=n=new E,C.l=y(p),qa(C),n.g="__noinit__",n.g=p,n.i(Error(n)),p=n;v=p}if(!(v instanceof B))throw v.h;}d=null!=d?d:"";if(c!=d){e=void 0;b={target:"_blank",noreferrer:!0};c=window;d instanceof M?f=d:(f="undefined"!=typeof d.href?d.href:String(d),f instanceof M||(f="object"==typeof f&&f.h?f.g():String(f),Oa.test(f)?f=new M(f,N):(f=String(f),f=f.replace(/(%0A|%0D)/g,""),f=(g=f.match(Na))&&Ma.test(g[1])?new M(f,N):null)),f=f||Qa);d=b.target||d.target;g=[];for(e in b)switch(e){case "width":case "height":case "top":case "left":g.push(e+
"="+b[e]);break;case "target":case "noopener":case "noreferrer":break;default:g.push(e+"="+(b[e]?1:0))}e=g.join(",");if((J("iPhone")&&!J("iPod")&&!J("iPad")||J("iPad")||J("iPod"))&&c.navigator&&c.navigator.standalone&&d&&"_self"!=d)e="A",g=document,e=String(e),"application/xhtml+xml"===g.contentType&&(e=e.toLowerCase()),g=e=g.createElement(e),f=f instanceof M?f:Pa(f),g.href=O(f),e.setAttribute("target",d),b.noreferrer&&e.setAttribute("rel","noreferrer"),b=document.createEvent("MouseEvent"),b.initMouseEvent("click",
!0,!0,c,1),e.dispatchEvent(b);else if(b.noreferrer){if(c=Sa("",c,d,e),b=O(f),c){Ua&&-1!=b.indexOf(";")&&(b="'"+b.replace(/'/g,"%27")+"'");c.opener=null;Ga.test(b)&&(-1!=b.indexOf("&")&&(b=b.replace(Aa,"&amp;")),-1!=b.indexOf("<")&&(b=b.replace(Ba,"&lt;")),-1!=b.indexOf(">")&&(b=b.replace(Ca,"&gt;")),-1!=b.indexOf('"')&&(b=b.replace(Da,"&quot;")),-1!=b.indexOf("'")&&(b=b.replace(Ea,"&#39;")),-1!=b.indexOf("\x00")&&(b=b.replace(Fa,"&#0;")));b='<meta name="referrer" content="no-referrer"><meta http-equiv="refresh" content="0; url='+
b+'">';if(void 0===K)if(d=null,(e=q.trustedTypes)&&e.createPolicy){try{d=e.createPolicy("goog#html",{createHTML:u,createScript:u,createScriptURL:u})}catch(v){q.console&&q.console.error(v.message)}K=d}else K=d;b=(d=K)?d.createHTML(b):b;b=new P(b,null,Ra);(c=c.document)&&c.write&&(c.write(b instanceof P&&b.constructor===P?b.i:"type_error:SafeHtml"),c.close())}}else(c=Sa(f,c,d,e))&&b.noopener&&(c.opener=null);a.g();break}}b=b.parentNode}};function pb(a){new ob(a)}
var X=["DOCS_installLinkReferrerSanitizer"],Y=q;X[0]in Y||"undefined"==typeof Y.execScript||Y.execScript("var "+X[0]);for(var Z;X.length&&(Z=X.shift());)X.length||void 0===pb?Y[Z]&&Y[Z]!==Object.prototype[Z]?Y=Y[Z]:Y=Y[Z]={}:Y[Z]=pb;}).call(this);
</script><script type="text/javascript" nonce="">DOCS_installLinkReferrerSanitizer();</script></body></html>